我正在 ClojureScript 应用程序中处理大型 JSON 文件(基本上包含树状结构)。基本上我会迭代该树结构中的所有元素,这些是相当多的操作。现在我想知道惰性 HashMap 处理会造成多少开销。
基本上我:
- 通过 AJAX 加载 JSON 文件
- 使用浏览器的
JSON.parse
将其转换为JS对象 - 使用
js->clj :keywordize-keys true
将其转换为clojure结构
JSON 的结构由嵌套列表和 HashMap 组成。类似的东西
{:A-key-a [{:B-key-a 34 :B-key-b [213. 23.4]}
{:B-key-a 34 :B-key-b [213. 23.4]}
...]
:A-key-b [{:someother-a 30 ...}
...]
...}
现在我想知道我是否应该回退到直接使用 JS 对象来获得速度。直觉上我认为这比 ClojureScript 对象更快,但另一方面我不想过早优化,而且我对 ClojureScript 的内部结构了解不够,无法判断延迟计算带来的开销。
我认为我可以使用 .-mykey
访问器语法和 google 闭包 foreach 函数来重写特定的源代码。你觉得怎么样?
我见过Improve performance of a ClojureScript program关于类似的优化主题,我认为这也意味着 loop .. recur
似乎是循环的可行选项。是这样吗?
最佳答案
如果它在您的控制之下,请考虑在服务器端生成 EDN 而不是 JSON。我不确定解析 EDN 字符串是否比将 JSON 转换为 EDN 更快,但至少它会在一定程度上降低应用程序的复杂性。
根据您的描述,听起来数据结构将是“只读”的。那么对象构造成本实际上是您必须考虑的唯一成本 - 稍后阅读它会很便宜(持久映射和向量具有接近恒定的访问时间)。
根据数据结构的大小,用户可能会也可能不会察觉到 UI 在页面加载时如何因该计算任务而阻塞。考虑测量它。
JS 数组可以被视为 seq,并且关键字键在 ClojureScript 中不如在 Clojure 中那么强大(这里它们没有实现 IFn
),实际上没有 <在这种特殊情况下,EDN 相对于 JSON 具有许多优势。
至于迭代,虽然映射/向量不是惰性的,但 Clojure(Script) 的数据处理函数(映射/过滤器/等)的结果确实返回惰性序列 - 并生成中间值收集的方式。
您可以通过使用最近移植的 reducers 来避免相关的开销库,以及transient
/persistent!
设施(如果这被证明是您应用程序中的实际问题)。
关于javascript - ClojureScript HashMap 性能与 Javascript 对象的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16772184/