Add benchmarks to README

This commit is contained in:
Jeff 2023-11-15 22:33:58 -05:00
parent 7445ebec34
commit ee87d322db

View File

@ -24,14 +24,16 @@ Dust is an interpreted, general purpose language with first class functions. It
- [Features](#features)
- [Usage](#usage)
- [Installation](#installation)
- [Benchmarks](#benchmarks)
- [Implementation](#implementation)
- [The Dust Programming Language](#the-dust-programming-language)
- [Declaring Variables](#declaring-variables)
- [Lists](#lists)
- [Maps](#maps)
- [Loops](#loops)
- [Tables](#tables)
- [Functions](#functions)
- [Concurrency](#concurrency)
- [Implementation](#implementation)
<!--toc:end-->
## Features
@ -58,6 +60,61 @@ You must have the default rust toolchain installed and up-to-date. Install [rust
To build from source, clone the repository and build the parser. To do so, enter the `tree-sitter-dust` directory and run `tree-sitter-generate`. In the project root, run `cargo run` to start the shell. To see other command line options, use `cargo run -- --help`.
## Benchmarks
Dust is at a very early development stage but performs strongly in preliminary benchmarks. The examples given were tested using [Hyperfine] on a single-core cloud instance with 1024 MB RAM. Each test was run 1000 times. The test script is shown below. Each test asks the program to read a JSON file and count the objects. The programs produced identical output with the exception that NodeJS printed in color.
For the first test, a file with four entries was used.
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `dust -c '(length (from_json input))' -p seaCreatures.json` | 3.1 ± 0.5 | 2.4 | 8.4 | 1.00 |
| `jq 'length' seaCreatures.json` | 33.7 ± 2.2 | 30.0 | 61.8 | 10.85 ± 1.87 |
| `node --eval "require('node:fs').readFile('seaCreatures.json', (err, data)=>{console.log(JSON.parse(data).length)})"` | 226.4 ± 13.1 | 197.6 | 346.2 | 73.02 ± 12.33 |
| `nu -c 'open seaCreatures.json \| length'` | 51.6 ± 3.7 | 45.4 | 104.3 | 16.65 ± 2.90 |
The second set of data is from the GitHub API, it consists of 100 commits from the jq GitHub repo.
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `dust -c '(length (from_json input))' -p jq_data.json` | 6.8 ± 0.6 | 5.7 | 12.0 | 2.20 ± 0.40 |
| `jq 'length' jq_data.json` | 43.3 ± 3.6 | 37.6 | 81.6 | 13.95 ± 2.49 |
| `node --eval "require('node:fs').readFile('jq_data.json', (err, data)=>{console.log(JSON.parse(data).length)})"` | 224.9 ± 12.3 | 194.8 | 298.5 | 72.52 ± 12.17 |
| `nu -c 'open jq_data.json \| length'` | 59.2 ± 5.7 | 49.7 | 125.0 | 19.11 ± 3.55 |
This data came from CERN, it is a massive file of 100,000 entries.
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `dust -c '(length (from_json input))' -p dielectron.json` | 1080.8 ± 38.7 | 975.3 | 1326.6 | 348.61 ± 56.71 |
| `jq 'length' dielectron.json` | 1305.3 ± 64.3 | 1159.7 | 1925.1 | 421.00 ± 69.94 |
| `node --eval "require('node:fs').readFile('dielectron.json', (err, data)=>{console.log(JSON.parse(data).length)})"` | 1850.5 ± 72.5 | 1641.9 | 2395.1 | 596.85 ± 97.54 |
| `nu -c 'open dielectron.json \| length'` | 1850.5 ± 86.2 | 1625.5 | 2400.7 | 596.87 ± 98.70 |
The tests were run after 5 warmup runs and the cache was cleared before each run.
```sh
hyperfine \
--shell none \
--warmup 5 \
--prepare "rm -rf /root/.cache" \
--runs 1000 \
--parameter-list data_path seaCreatures.json,jq_data.json,dielectron.json \
--export-markdown test_output.md \
"dust -c '(length (from_json input))' -p {data_path}" \
"jq 'length' {data_path}" \
"node --eval \"require('node:fs').readFile('{data_path}',(err,data)=>{console.log(JSON.parse(data).length)})\"" \
"nu -c 'open {data_path} | length'"
```
## Implementation
Dust is formally defined as a Tree Sitter grammar in the tree-sitter-dust directory. Tree sitter generates a parser, written in C, from a set of rules defined in JavaScript. Dust itself is a rust binary that calls the C parser using FFI.
Tests are written in three places: in the Rust library, in Dust as examples and in the Tree Sitter test format. Generally, features are added by implementing and testing the syntax in the tree-sitter-dust repository, then writing library tests to evaluate the new syntax. Implementation tests run the Dust files in the "examples" directory and should be used to demonstrate and verify that features work together.
Tree Sitter generates a concrete syntax tree, which Dust traverses to create an abstract syntax tree that can run the Dust code. The CST generation is an extra step but it allows easy testing of the parser, defining the language in one file and makes the syntax easy to modify and expand. Because it uses Tree Sitter, developer-friendly features like syntax highlighting and code navigation are already available in any text editor that supports Tree Sitter.
## The Dust Programming Language
Dust is easy to learn. Aside from this guide, the best way to learn Dust is to read the examples and tests to get a better idea of what it can do.
@ -260,14 +317,6 @@ data = async {
}
```
## Implementation
Dust is formally defined as a Tree Sitter grammar in the tree-sitter-dust directory. Tree sitter generates a parser, written in C, from a set of rules defined in Javascript. Dust itself is a rust binary that calls the C parser using FFI.
Tests are written in three places: in the Rust library, in Dust as examples and in the Tree Sitter test format. Generally, features are added by implementing and testing the syntax in the tree-sitter-dust repository, then writing library tests to evaluate the new syntax. Implementation tests run the Dust files in the "examples" directory and should be used to demonstrate and verify that features work together.
Tree Sitter generates a concrete syntax tree, which Dust traverses to create an abstract syntax tree that can run the Dust code. The CST generation is an extra step but it allows easy testing of the parser, defining the language in one file and makes the syntax easy to modify and expand. Because it uses Tree Sitter, developer-friendly features like syntax highlighting and code navigation are already available in any text editor that supports Tree Sitter.
[Tree Sitter]: https://tree-sitter.github.io/tree-sitter/
[Rust]: https://rust-lang.org
[dnf]: https://dnf.readthedocs.io/en/latest/index.html