https://github.com/rescript-association/bs-list-benchmark
Discussion of the internal data representation of immutable lists
https://github.com/rescript-association/bs-list-benchmark
Last synced: about 2 months ago
JSON representation
Discussion of the internal data representation of immutable lists
- Host: GitHub
- URL: https://github.com/rescript-association/bs-list-benchmark
- Owner: rescript-association
- Created: 2019-06-30T11:12:19.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2019-07-01T20:17:36.000Z (almost 6 years ago)
- Last Synced: 2024-08-04T01:27:40.228Z (11 months ago)
- Language: JavaScript
- Size: 3.91 KB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-list - bs-list-benchmark - association | 6 | (JavaScript)
README
# BuckleScript List Benchmark
This benchmark demonstrates how to optimize list iteration speed in almost all major
JS engines by tweaking the internal runtime representation.As for right now, the expression `let myList = ["a", "b", "c"]` is compiled to
following JavaScript:```
var myList = /* :: */[
"a",
/* :: */[
"b",
/* :: */[
"c",
/* [] */0
]
]
];
```Note how the last element in the array is terminated with a `0` value. This
will cause V8 to do a [kind
transition](https://v8.dev/blog/elements-kinds#avoid-elements-kind-transitions)
to a polymorphic kind [which ideally should be
avoided](https://v8.dev/blog/elements-kinds#avoid-polymorphism).To prevent this, the internal list representation must be terminated with a non-SMI value, such as
`false`, `null`, etc:```
var myList = /* :: */[
"a",
/* :: */[
"b",
/* :: */[
"c",
/* [] */null
]
]
];
```## Setup
```
npm install jsvu -g# Make sure to tick chakra, javascriptcore, spidermonkey, v8 and v8-debug
jsvu
```## Run full Benchmark
```
# Will run the performance test for each JS engine
./benchmark.sh
```**Test Results:**
Macbook Pro 13" 2016, 3,3 GHz Intel Core i7, 16GB ram
The benchmark does 3 runs per `original` / `optimized` group to make sure that
there are no warm-up side-effects. Each function is called `1e7` times to
ensure an obversable time diff.The optimized function uses `null` as list terminator, the original function uses
a `0` (current behavior in BuckleScript). The test source code can be found in [`./perf.js`](./perf.js).```
./benchmark.shRun V8:
optimized: 1242 ms.
original: 1722 ms.
optimized: 1263 ms.
original: 1734 ms.
optimized: 1233 ms.
original: 1760 ms.Run JavaSciptCore:
optimized: 430 ms.
original: 835 ms.
optimized: 881 ms.
original: 936 ms.
optimized: 859 ms.
original: 938 ms.Run SpiderMonkey:
optimized: 542 ms.
original: 492 ms.
optimized: 567 ms.
original: 482 ms.
optimized: 546 ms.
original: 518 ms.Run Chakra:
optimized: 1112 ms.
original: 3575 ms.
optimized: 908 ms.
original: 3479 ms.
optimized: 894 ms.
original: 3513 ms.
```There are some interesting observations:
- ~30% better V8 / Chakra performance
- -9% worse performance in SpiderMonkey, but the performance there is already 3 times as fast as V8
- Not sure why, but in JSC, the first call has a huge gap with +51% performance boost, while every other call is only around +6%## Credits
Thanks to @bmeurer for explaining element kinds mechanic in V8, how to
interpret the bytecode debugging output and writing the performance tests.**Links:**
- [V8 Element Kinds | V8 Dev Blog](https://v8.dev/blog/elements-kinds#the-elements-kind-lattice)