ClojureScript

str macro emits unoptimizable js code

Details

  • Type: Enhancement Enhancement
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Environment:
    r2202
  • Patch:
    Code and Test

Description

Clojurescript's str macro emits javascript code which is inefficient and which the closure compiler cannot optimize.

Currently it emits code like {{[cljs.core.str(arg1),cljs.core.str(arg2)].join('')}}. The problems with this:

  1. The emitted function is the arity-dispatch str wrapper instead of the 1-arg implementation of str. The closure compiler cannot eliminate the dispatch.
  2. An intermediate array is always created; the closure compiler cannot optimize it out.
  3. The closure compiler can evaluate constant string expressions (e.g. 'a'+1 to 'a1'), but cannot in this case because it cannot eliminate the str call.

The attached patch rewrites the str macro to generate js code that looks like this:

(str arg1 "constant" \space true nil 123 456.78)

(""+cljs.core.str.cljs$core$IFn$_invoke$arity$1(arg1)+"constant "+true+123+456.78)

This has a number of benefits:

  1. No short-lived array or Array.join operation.
  2. No arity dispatch is invoked. I have also observed that it can (but won't necessarily) inline the function body.
  3. The compiler can perform constant evaluation. For example, in advanced mode the compiler will emit the above example as (""+w.c(a)+"constant true123456.78") where w.c is the munged cljs.core.str.cljs$core$IFn$_invoke$arity$1
  1. cljs-801.patch
    28/Apr/14 12:04 AM
    3 kB
    Francis Avila
  2. cljs-801-v2.patch
    28/Apr/14 12:17 AM
    3 kB
    Francis Avila
  3. cljs-801-v3.patch
    11/May/14 1:38 AM
    3 kB
    Francis Avila
  4. cljs-801-v4.patch
    11/May/14 11:22 AM
    3 kB
    Francis Avila

Activity

Hide
Francis Avila added a comment -

Updated patch adds booleans to the str test case, and does not eagerly stringify bools anymore. (It emits as literals and lets the closure compiler decide to stringify at compile time if it wants.)

Show
Francis Avila added a comment - Updated patch adds booleans to the str test case, and does not eagerly stringify bools anymore. (It emits as literals and lets the closure compiler decide to stringify at compile time if it wants.)
Hide
David Nolen added a comment -

Need the patch rebased to master.

Show
David Nolen added a comment - Need the patch rebased to master.
Hide
Francis Avila added a comment -

Updated patch.

Show
Francis Avila added a comment - Updated patch.
Hide
David Nolen added a comment -

Sorry because of the last commit to master this ticket will not apply, please rebase again. I'll refrain from adding tests until this one gets merged in

Show
David Nolen added a comment - Sorry because of the last commit to master this ticket will not apply, please rebase again. I'll refrain from adding tests until this one gets merged in
Hide
Francis Avila added a comment -

No problem, updated patch.

Show
Francis Avila added a comment - No problem, updated patch.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: