Matches now use memcpy and memset when possible.
Block loops have been rewritten to be more optimizer friendly.
Reworks Symbol and HuffmanDecoder
- Symbol now only includes the value and number of code bits. decodeSymbol returns only the value.
- HuffmanDecoder now takes the regular bits instead of the reversed.
- Code table construction now uses buckets instead of sorting.
- For linked codes, the value field of Symbol is now used as the next index. The actual value is the element index.
- InvalidCode is now detected only once with a special linked index.
Performance against master:
Benchmark 1 (125 runs): .extra/run-with-stdin.sh ./jit-inflate-base /tmp/dev/src.tar.gz
measurement mean ± σ min ... max outliers delta
wall_time 40.2ms ± 457us 39.5ms ... 41.6ms 3 ( 2%) 0%
peak_rss 5.60MB ± 131KB 5.26MB ... 5.91MB 0 ( 0%) 0%
cpu_cycles 172M ± 700K 172M ... 176M 7 ( 6%) 0%
instructions 416M ± 339 416M ... 416M 0 ( 0%) 0%
cache_references 2.63M ± 37.2K 2.53M ... 2.71M 2 ( 2%) 0%
cache_misses 44.4K ± 2.32K 38.8K ... 58.9K 5 ( 4%) 0%
branch_misses 2.41M ± 2.33K 2.40M ... 2.42M 3 ( 2%) 0%
Benchmark 2 (205 runs): .extra/run-with-stdin.sh ./jit-inflate /tmp/dev/src.tar.gz
measurement mean ± σ min ... max outliers delta
wall_time 24.4ms ± 443us 22.8ms ... 25.6ms 7 ( 3%) ⚡- 39.2% ± 0.2%
peak_rss 5.64MB ± 126KB 5.31MB ... 5.91MB 0 ( 0%) + 0.8% ± 0.5%
cpu_cycles 97.5M ± 215K 97.2M ... 98.1M 0 ( 0%) ⚡- 43.4% ± 0.1%
instructions 252M ± 414 252M ... 252M 3 ( 1%) ⚡- 39.5% ± 0.0%
cache_references 2.28M ± 33.2K 2.17M ... 2.36M 5 ( 2%) ⚡- 13.3% ± 0.3%
cache_misses 42.8K ± 1.70K 39.5K ... 48.4K 2 ( 1%) ⚡- 3.8% ± 1.0%
branch_misses 972K ± 2.12K 967K ... 979K 4 ( 2%) ⚡- 59.6% ± 0.0%
Performance against gzip:
Benchmark 1 (203 runs): .extra/run-with-stdin.sh gunzip /tmp/dev/src.tar.gz
measurement mean ± σ min ... max outliers delta
wall_time 24.7ms ± 498us 23.5ms ... 26.5ms 7 ( 3%) 0%
peak_rss 5.70MB ± 87.5KB 5.28MB ... 5.90MB 1 ( 0%) 0%
cpu_cycles 97.9M ± 552K 97.3M ... 100M 26 (13%) 0%
instructions 187M ± 522 187M ... 187M 3 ( 1%) 0%
cache_references 1.67M ± 89.6K 1.55M ... 2.17M 16 ( 8%) 0%
cache_misses 88.1K ± 4.78K 76.5K ... 104K 5 ( 2%) 0%
branch_misses 2.01M ± 3.59K 2.00M ... 2.02M 5 ( 2%) 0%
Benchmark 2 (205 runs): .extra/run-with-stdin.sh ./jit-inflate /tmp/dev/src.tar.gz
measurement mean ± σ min ... max outliers delta
wall_time 24.4ms ± 452us 23.0ms ... 25.7ms 2 ( 1%) - 1.0% ± 0.4%
peak_rss 5.63MB ± 130KB 5.27MB ... 5.90MB 1 ( 0%) - 1.2% ± 0.4%
cpu_cycles 97.6M ± 506K 97.1M ... 102M 8 ( 4%) - 0.3% ± 0.1%
instructions 252M ± 485 252M ... 252M 8 ( 4%) 💩+ 34.6% ± 0.0%
cache_references 2.29M ± 117K 2.18M ... 3.69M 9 ( 4%) 💩+ 37.7% ± 1.2%
cache_misses 42.9K ± 1.89K 38.6K ... 51.5K 7 ( 3%) ⚡- 51.3% ± 0.8%
branch_misses 972K ± 1.79K 968K ... 977K 0 ( 0%) ⚡- 51.5% ± 0.0%
Matches now use memcpy and memset when possible.
Block loops have been rewritten to be more optimizer friendly.
Reworks Symbol and HuffmanDecoder
* Symbol now only includes the value and number of code bits. decodeSymbol returns only the value.
* HuffmanDecoder now takes the regular bits instead of the reversed.
* Code table construction now uses buckets instead of sorting.
* For linked codes, the value field of Symbol is now used as the next index. The actual value is the element index.
* InvalidCode is now detected only once with a special linked index.
Performance against master:
```
Benchmark 1 (125 runs): .extra/run-with-stdin.sh ./jit-inflate-base /tmp/dev/src.tar.gz
measurement mean ± σ min ... max outliers delta
wall_time 40.2ms ± 457us 39.5ms ... 41.6ms 3 ( 2%) 0%
peak_rss 5.60MB ± 131KB 5.26MB ... 5.91MB 0 ( 0%) 0%
cpu_cycles 172M ± 700K 172M ... 176M 7 ( 6%) 0%
instructions 416M ± 339 416M ... 416M 0 ( 0%) 0%
cache_references 2.63M ± 37.2K 2.53M ... 2.71M 2 ( 2%) 0%
cache_misses 44.4K ± 2.32K 38.8K ... 58.9K 5 ( 4%) 0%
branch_misses 2.41M ± 2.33K 2.40M ... 2.42M 3 ( 2%) 0%
Benchmark 2 (205 runs): .extra/run-with-stdin.sh ./jit-inflate /tmp/dev/src.tar.gz
measurement mean ± σ min ... max outliers delta
wall_time 24.4ms ± 443us 22.8ms ... 25.6ms 7 ( 3%) ⚡- 39.2% ± 0.2%
peak_rss 5.64MB ± 126KB 5.31MB ... 5.91MB 0 ( 0%) + 0.8% ± 0.5%
cpu_cycles 97.5M ± 215K 97.2M ... 98.1M 0 ( 0%) ⚡- 43.4% ± 0.1%
instructions 252M ± 414 252M ... 252M 3 ( 1%) ⚡- 39.5% ± 0.0%
cache_references 2.28M ± 33.2K 2.17M ... 2.36M 5 ( 2%) ⚡- 13.3% ± 0.3%
cache_misses 42.8K ± 1.70K 39.5K ... 48.4K 2 ( 1%) ⚡- 3.8% ± 1.0%
branch_misses 972K ± 2.12K 967K ... 979K 4 ( 2%) ⚡- 59.6% ± 0.0%
```
Performance against gzip:
```
Benchmark 1 (203 runs): .extra/run-with-stdin.sh gunzip /tmp/dev/src.tar.gz
measurement mean ± σ min ... max outliers delta
wall_time 24.7ms ± 498us 23.5ms ... 26.5ms 7 ( 3%) 0%
peak_rss 5.70MB ± 87.5KB 5.28MB ... 5.90MB 1 ( 0%) 0%
cpu_cycles 97.9M ± 552K 97.3M ... 100M 26 (13%) 0%
instructions 187M ± 522 187M ... 187M 3 ( 1%) 0%
cache_references 1.67M ± 89.6K 1.55M ... 2.17M 16 ( 8%) 0%
cache_misses 88.1K ± 4.78K 76.5K ... 104K 5 ( 2%) 0%
branch_misses 2.01M ± 3.59K 2.00M ... 2.02M 5 ( 2%) 0%
Benchmark 2 (205 runs): .extra/run-with-stdin.sh ./jit-inflate /tmp/dev/src.tar.gz
measurement mean ± σ min ... max outliers delta
wall_time 24.4ms ± 452us 23.0ms ... 25.7ms 2 ( 1%) - 1.0% ± 0.4%
peak_rss 5.63MB ± 130KB 5.27MB ... 5.90MB 1 ( 0%) - 1.2% ± 0.4%
cpu_cycles 97.6M ± 506K 97.1M ... 102M 8 ( 4%) - 0.3% ± 0.1%
instructions 252M ± 485 252M ... 252M 8 ( 4%) 💩+ 34.6% ± 0.0%
cache_references 2.29M ± 117K 2.18M ... 3.69M 9 ( 4%) 💩+ 37.7% ± 1.2%
cache_misses 42.9K ± 1.89K 38.6K ... 51.5K 7 ( 3%) ⚡- 51.3% ± 0.8%
branch_misses 972K ± 1.79K 968K ... 977K 0 ( 0%) ⚡- 51.5% ± 0.0%
```