ClojureScript

Optimize string expression concatenation

Details

  • Type: Enhancement Enhancement
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Patch:
    Code and Test
  • Approval:
    Accepted

Description

Now that we have function return type inference (CLJS-1997), we can see that functions like namespace return strings. Additionally, we can easily make it so that expressions involving str are inferred as returning strings. With those two in place, with a mild extension to CLJS-2314, we can eliminate unnecessary string coercions in str macro expansions where arguments are inferred to be strings.

This leads to performance gains which are akin to checked-if elimination (but perhaps even greater):

(defn foo [x y]
  (str (+ x y)))

(simple-benchmark [x :foo/bar] (str (namespace x) "-" (foo 3 2)) 10000000)

Yields these speedups under :advanced

V8: 3.2
SpiderMonkey: 1.3
JavaScriptCore: 4.2
Nashorn: 2.5
ChakraCore: 3.2
GraalVM: 1.3

This could be great for UIs that are heavy in string-concatenation, as well as for the self-hosted compiler.

Details:

Before:

Benchmarking with V8
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 1686 msecs
Benchmarking with SpiderMonkey
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 1845 msecs
Benchmarking with JavaScriptCore
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 7973 msecs
Benchmarking with Nashorn
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 37874 msecs
Benchmarking with ChakraCore
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 4899 msecs
Benchmarking with GraalVM
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 955 msecs

After:

Benchmarking with V8
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 518 msecs
Benchmarking with SpiderMonkey
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 1340 msecs
Benchmarking with JavaScriptCore
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 1859 msecs
Benchmarking with Nashorn
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 15276 msecs
Benchmarking with ChakraCore
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 1496 msecs
Benchmarking with GraalVM
[x :foo/bar], (str (namespace x) "-" (foo 3 2)), 10000000 runs, 683 msecs
  1. CLJS-2865.patch
    19/Aug/18 8:12 AM
    2 kB
    Mike Fikes
  2. CLJS-2865-2.patch
    20/Aug/18 9:02 AM
    3 kB
    Mike Fikes
  3. CLJS-2865-3.patch
    04/Sep/18 8:47 PM
    3 kB
    Mike Fikes
  4. CLJS-2865-4.patch
    26/Oct/18 6:52 AM
    3 kB
    Mike Fikes
  5. CLJS-2865-5.patch
    08/Nov/18 7:08 PM
    3 kB
    Mike Fikes

Activity

Hide
Mike Fikes added a comment - - edited

Assigning back to me to look into handling elimination of coercions for nil. This is also feasible (as js/undefined also works out), and would handle the important pattern of

(str "x" (when test "y"))
Show
Mike Fikes added a comment - - edited Assigning back to me to look into handling elimination of coercions for nil. This is also feasible (as js/undefined also works out), and would handle the important pattern of
(str "x" (when test "y"))
Hide
Mike Fikes added a comment -

CLJS-2865-2.patch adds support for avoiding coercion for inferred clj-nil, along with some tests. (This patch also passes all the Canary tests.)

Show
Mike Fikes added a comment - CLJS-2865-2.patch adds support for avoiding coercion for inferred clj-nil, along with some tests. (This patch also passes all the Canary tests.)
Hide
Mike Fikes added a comment -

CLJS-2865-3.patch is the same as CLJS-2865-2.patch except that it uses the parameter name form in a few places where ast was previously used.

Show
Mike Fikes added a comment - CLJS-2865-3.patch is the same as CLJS-2865-2.patch except that it uses the parameter name form in a few places where ast was previously used.
Hide
Mike Fikes added a comment -

Patch no longer applies.

Show
Mike Fikes added a comment - Patch no longer applies.
Hide
Mike Fikes added a comment -

CLJS-2865-4.patch rebaselines

Show
Mike Fikes added a comment - CLJS-2865-4.patch rebaselines
Hide
Mike Fikes added a comment -

CLJS-2865-4.patch no longer applies

Show
Mike Fikes added a comment - CLJS-2865-4.patch no longer applies
Hide
Mike Fikes added a comment -

CLJS-2865-5.patch rebaselines while also accommodating the changes in CLJS-2864 that are currently on master.

This revision of the patch passes CI, Canary, and shows no slowdown when compiling the Coal Mine corpus.

Show
Mike Fikes added a comment - CLJS-2865-5.patch rebaselines while also accommodating the changes in CLJS-2864 that are currently on master. This revision of the patch passes CI, Canary, and shows no slowdown when compiling the Coal Mine corpus.

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: