reagent icon indicating copy to clipboard operation
reagent copied to clipboard

Optimize dash-to-prop-name & capitalize fns

Open roman01la opened this issue 6 years ago • 6 comments

This PR optimizes string manipulation code in reagent.impl.util/dash-to-prop-name and reagent.impl.util/capitalize which results in ~34% speedup when interpreting Hiccup, according to synthetic benchmark added here.

I suspect similar optimizations could be done in other parts of code base, but this can be done in separate PRs.

roman01la avatar Sep 10 '19 20:09 roman01la

So, I did some testing with this:

  • Currently this doesn't work as destructuring will return parts as Seq, not Array
  • array-reduce is private in cljs.core
  • I can't see any performance different with Firefox or Chrome here, 5000ms with the old function and the new in both browsers.
  • Test case contains lots of hiccup tags with classes, but this change doesn't affect tag name parsing, which might explain why I don't see change.

I tested version like this, where destructuring is not used so split result is kept as Array:

(defn dash-to-prop-name [dashed]
  (if (string? dashed)
    dashed
    (let [name-str (name dashed)
          parts (.split name-str #"-")
          start (aget parts 0)]
      (cond
        (contains? dont-camel-case start) name-str

        (> (.-length parts) 1)
        (-> (array-reduce
              parts
              (fn [a p]
                (.push a (capitalize p))
                a)
              #js [start]
              1)
            (.join ""))

        :else start))))

Deraen avatar Oct 17 '19 12:10 Deraen

I think we can use normal reduce here and it will fall into array-reduce when applied to js/Array. Perf difference should be noticeable for Hiccup with lots of attributes and inline styles.

roman01la avatar Oct 17 '19 12:10 roman01la

Yes, reduce is probably fine. Though it doesn't directly call arrray-reduce. When destructuring is used to get start and parts, parts will be ArrayChunk which has it's own IReduce implementation using array-reduce and offset.

I'll look more into this after getting 0.9 finally out.

Probably benchmarking the dash-to-prop-name alone, preferably with Benchmark.js, should provide more information about this change.

Deraen avatar Oct 17 '19 12:10 Deraen

Pushed an update to avoid implicit conversion to a seq when destructuring js/array

roman01la avatar Oct 22 '19 10:10 roman01la

@Deraen Is there anything blocking this PR from getting merged?

roman01la avatar Sep 30 '21 10:09 roman01la

I think I was unsure of the performance improvements last I tried to benchmark this.

Probably benchmarking the dash-to-prop-name alone, preferably with Benchmark.js, should provide more information about this change.

Deraen avatar Oct 01 '21 06:10 Deraen