Skip to content

Commit f9a6856

Browse files
authored
Experimental Lite Mode (#265)
new code-size compiler flags: :lite-mode, :elide-to-string :lite-mode emits updated variants of the original copy-on-write data structures from 2011. Notably, in `:lite-mode` chunked-seqs are not supported as they pull in a significant amount of code, which defeats the purpose of the new flags. Also while the transient interfaces are implemented on the copy-on-write data structures, they do not actually provide a fast path. This is not by design, but simply a practical scoping of effort as the work done here is already considerable. The other serious code-size issue are `.toString` impls. There are many interesting smaller programs that simply do not need the convenient `.toString` invoking the ClojureScript recursive printing machinery. By combining `:lite-mode true` with `:elide-to-string true` the emitted code is cut in half or more for simpler programs. For a rough idea of the space-savings, a hash-map literal is ~6K after advanced compilation with the new flags and brotli compression. ClojureScript 1.12.42 is ~17K brotli for the same program. The following expression (.log js/console (->> (map inc (range 10)) (filter even?) (partition 2) (drop 1) (mapcat identity) into-array)) Is ~6K after advanced compilation + brotli compression. ClojureScript is 1.12.42 is ~19K. For users that want the full expressiveness of the Clojure APIs and the interactivity of the REPL for smaller and/or simpler projects, but don't need every last bit of performance, these two flags should lead to compact artifacts.
1 parent ddf3cfe commit f9a6856

File tree

20 files changed

+1391
-279
lines changed

20 files changed

+1391
-279
lines changed

.github/workflows/test.yaml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,63 @@ jobs:
5959
/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Helpers/jsc builds/out-adv/core-advanced-test.js | tee test-out.txt
6060
grep -qxF '0 failures, 0 errors.' test-out.txt
6161
62+
# Lite Tests
63+
lite-test:
64+
name: Lite Tests
65+
runs-on: macos-14
66+
steps:
67+
- uses: actions/checkout@v2
68+
69+
- uses: actions/setup-java@v4
70+
with:
71+
distribution: 'temurin'
72+
java-version: '21'
73+
74+
- uses: DeLaGuardo/[email protected]
75+
with:
76+
tools-deps: '1.10.1.763'
77+
78+
- name: Cache maven
79+
uses: actions/cache@v4
80+
env:
81+
cache-name: cache-maven
82+
with:
83+
path: ~/.m2
84+
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/deps.edn') }}
85+
restore-keys: |
86+
${{ runner.os }}-${{ env.cache-name }}-
87+
88+
- name: Cache gitlibs
89+
uses: actions/cache@v4
90+
env:
91+
cache-name: cache-gitlibs
92+
with:
93+
path: ~/.gitlibs
94+
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/deps.edn') }}
95+
restore-keys: |
96+
${{ runner.os }}-${{ env.cache-name }}-
97+
98+
# - name: Cache JSC
99+
# uses: actions/cache@v4
100+
# env:
101+
# cache-name: cache-jsc
102+
# with:
103+
# path: WebKit
104+
# key: ${{ runner.os }}-jsc
105+
# restore-keys: |
106+
# ${{ runner.os }}-jsc
107+
108+
- name: Build tests
109+
run: clojure -M:lite.test.build
110+
111+
# - name: Install JSC
112+
# run: ./ci/install_jsc.sh
113+
114+
- name: Run tests
115+
run: |
116+
/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Helpers/jsc builds/out-lite/lite-test.js | tee test-out.txt
117+
grep -qxF '0 failures, 0 errors.' test-out.txt
118+
62119
# Runtime Tests
63120
runtime-windows-test:
64121
name: Runtime Windows Tests

deps.edn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
"-e" "(cljs.test-runner/-main)"]}
2020
:runtime.test.build {:extra-paths ["src/test/cljs"]
2121
:main-opts ["-m" "cljs.main" "-co" "resources/test.edn" "-c"]}
22+
:lite.test.build {:extra-paths ["src/test/cljs"]
23+
:main-opts ["-m" "cljs.main" "-co" "resources/lite_test.edn" "-c"]}
2224
:selfhost.test.build {:extra-paths ["src/test/self"]
2325
:main-opts ["-m" "cljs.main" "-co" "resources/self_host_test.edn" "-c"]}
2426
:selfparity.test.build {:extra-paths ["src/test/self"]

resources/lite_test.edn

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{:optimizations :advanced
2+
:main lite-test-runner
3+
:output-to "builds/out-lite/lite-test.js"
4+
:output-dir "builds/out-lite"
5+
:output-wrapper true
6+
:verbose true
7+
:compiler-stats true
8+
:parallel-build true
9+
:npm-deps {:lodash "4.17.4"}
10+
:closure-warnings {:non-standard-jsdoc :off :global-this :off}
11+
:install-deps true
12+
:language-out :es5
13+
:foreign-libs
14+
[{:file "src/test/cljs/calculator_global.js"
15+
:provides ["calculator"]
16+
:global-exports {calculator Calculator}}
17+
{:file "src/test/cljs/es6_dep.js"
18+
:module-type :es6
19+
:provides ["es6_calc"]}
20+
{:file "src/test/cljs/calculator.js"
21+
:module-type :commonjs
22+
:provides ["calculator"]}
23+
{:file "src/test/cljs/es6_default_hello.js"
24+
:provides ["es6_default_hello"]
25+
:module-type :es6}]
26+
:pseudo-names true
27+
:pretty-print true
28+
:lite-mode true}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
;; Copyright (c) Rich Hickey. All rights reserved.
2+
;; The use and distribution terms for this software are covered by the
3+
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
;; which can be found in the file epl-v10.html at the root of this distribution.
5+
;; By using this software in any fashion, you are agreeing to be bound by
6+
;; the terms of this license.
7+
;; You must not remove this notice, or any other, from this software.
8+
9+
(ns cljs.analyzer.passes.lite
10+
(:refer-clojure :exclude [var?]))
11+
12+
(defn var? [ast]
13+
(= :var (:op ast)))
14+
15+
(def ctor->simple-ctor
16+
'{cljs.core/vector cljs.core/simple-vector
17+
cljs.core/vec cljs.core/simple-vec})
18+
19+
(defn update-var [{:keys [name] :as ast}]
20+
(let [replacement (get ctor->simple-ctor name)]
21+
(-> ast
22+
(assoc :name replacement)
23+
(assoc-in [:info :name] replacement))))
24+
25+
(defn replace-var? [ast]
26+
(and (var? ast)
27+
(contains? ctor->simple-ctor (:name ast))))
28+
29+
(defn use-lite-types
30+
[env ast _]
31+
(cond-> ast
32+
(replace-var? ast) update-var))

0 commit comments

Comments
 (0)