2

I am working with big JSON files (that basically contain tree-like structures) in a ClojureScript app. Basically I iterate over all elements in that tree structure and these are quite a bunch of operations. Now I wonder how much overhead the Lazy Hash map treatment causes.

Basically I:

  • Load the JSON file via AJAX
  • Convert it to a JS object using browser's JSON.parse
  • use js->clj :keywordize-keys true to convert it to a clojure structure

The JSON's structure consists of nested lists and hash-maps. Something like

{: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 ...}
                   ...]
 ...}

Now I wonder if I should fall back to direct JS object usage to gain spped. Intuitively I would think that this is faster than the ClojureScript objects on the other hand I do not want to optimize prematurely and I do not know enough about the internals of ClojureScript in order to judge the overheads introduced by lazy evaluation.

I kind of figure that I could use .-mykey accessor syntax and google closure foreach functions in order to rewrite that specific source code. What do you think?

I have seen Improve performance of a ClojureScript program on a similar optimation topic and I think this also implies that loop .. recur seems to be a viable option for looping. Is that right?

3
  • 2
    Clojure(script) maps are not lazy :) only lazy sequences (different from both lists and vectors) are.
    – deprecated
    Commented May 27, 2013 at 12:56
  • Perhaps youi'd like to specify how are you going to use the data structure: do you need to model change upon it?
    – deprecated
    Commented May 27, 2013 at 12:58
  • I added a schematic of the json file into the main question. I mentioned hash maps a lot because I probably took them to be the culprit.
    – wirrbel
    Commented May 27, 2013 at 15:33

1 Answer 1

2

If it is under your control, consider producing EDN instead of JSON on the server side. I'm not sure if parsing a EDN string is faster than converting JSON to EDN, but at the very least it will reduce your app's complexity to some degree.

As per your description, it sounds like the data structure will be "read-only". Then the object construction cost is practically the only one you have to consider - reading it later will be cheap (persistent maps and vectors have near-constant access time).

Depending on the data structure size, the user might or not might not perceive how the UI blocks due to this computational task at page-load time. Consider measuring it.

Between that JS arrays can be treated as seqs, and that keyword keys are not as powerful in ClojureScript as they are in Clojure (here they do not implement IFn), there actually aren't that many advantages of EDN over JSON in this particular case.

As for iteration, while maps/vectors aren't lazy, the results of Clojure(Script)'s data processing functions (map/filter/etc) do return lazy sequences - and generate intermediate collections in the way.

You can avoid the associated overhead by using the recently-ported reducers library, and the transient/persistent! facilities (if this turned out to be an actual issue in your app).

1
  • 1
    Keywords can absolutely be used as functions in ClojureScript. (How the function call is accomplished depends on whether the keyword is a literal in the operator position of a form or not; it works in either case.) Also, the reducers library has been available in ClojureScript pretty much immediately after it was introduced to Clojure (although there's been a few bug fixes since). Commented May 30, 2013 at 4:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.