An implementation of Unix dc and POSIX bc with GNU and BSD extensions
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

313 lines
4.0 KiB

3 years ago
# Benchmarks
These are the results of benchmarks comparing this `bc` (at version `2.0.3`) and
3 years ago
GNU `bc` (at version `1.07.1`).
Note: all benchmarks were run four times, and the fastest run is the one shown.
3 years ago
Also, `[bc]` means whichever `bc` was being run, and the assumed working
directory is the root directory of this repository. Also, this `bc` was built at
`-O2`.
### Addition
The command used was:
```
tests/script.sh bc add.bc 0 1 1 [bc]
3 years ago
```
For GNU `bc`:
```
Running bc script: add.bc
real 2.24
user 1.13
sys 1.11
3 years ago
```
For this `bc`:
```
Running bc script: add.bc
real 1.32
user 1.30
sys 0.02
3 years ago
```
### Subtraction
The command used was:
```
tests/script.sh bc subtract.bc 0 1 1 [bc]
3 years ago
```
For GNU `bc`:
```
Running bc script: subtract.bc
real 2.28
user 1.33
sys 0.94
3 years ago
```
For this `bc`:
```
Running bc script: subtract.bc
real 1.37
user 1.34
sys 0.02
3 years ago
```
### Multiplication
The command used was:
```
tests/script.sh bc multiply.bc 0 1 1 [bc]
3 years ago
```
For GNU `bc`:
```
Running bc script: multiply.bc
real 6.02
user 4.06
sys 1.92
3 years ago
```
For this `bc`:
```
Running bc script: multiply.bc
real 2.59
user 2.53
sys 0.05
3 years ago
```
### Division
The command used was:
```
tests/script.sh bc divide.bc 0 1 1 [bc]
3 years ago
```
For GNU `bc`:
```
Running bc script: divide.bc
real 2.94
user 1.85
sys 1.09
3 years ago
```
For this `bc`:
```
Running bc script: divide.bc
real 1.91
user 1.90
sys 0.00
3 years ago
```
### Power
The command used was:
```
printf '1234567890^100000; halt\n' | time -p [bc] -lq > /dev/null
```
For GNU `bc`:
```
real 11.81
user 11.80
3 years ago
sys 0.00
```
For this `bc`:
```
real 0.76
user 0.75
3 years ago
sys 0.00
```
### Scripts
[This file][1] was downloaded, saved at `../timeconst.bc` and the following
patch was applied:
```
--- tests/bc/scripts/timeconst.bc 2018-09-28 11:32:22.808669000 -0600
+++ ../timeconst.bc 2019-06-07 07:26:36.359913078 -0600
@@ -108,8 +108,10 @@
print "#endif /* KERNEL_TIMECONST_H */\n"
}
- halt
}
-hz = read();
-timeconst(hz)
+for (i = 0; i <= 10000; ++i) {
+ timeconst(i)
+}
+
+halt
```
The command used was:
```
time -p [bc] ../timeconst.bc > /dev/null
```
For GNU `bc`:
```
real 3.03
user 2.90
sys 0.13
```
For this `bc`:
```
real 2.64
user 2.64
sys 0.00
```
Because this `bc` is faster when doing math, it might be a better comparison to
run a script that is not running any math. As such, I put the following into
`../test.bc`:
```
for (i = 0; i < 100000000; ++i) {
y = i
}
i
y
halt
```
The command used was:
```
time -p [bc] ../test.bc > /dev/null
```
For GNU `bc`:
```
real 13.46
user 13.46
sys 0.00
```
For this `bc`:
```
real 24.72
user 24.72
sys 0.00
```
However, when I put the following into `../test2.bc`:
```
i = 0
while (i < 100000000) {
++i
}
i
halt
```
the results were surprising.
The command used was:
```
time -p [bc] ../test2.bc > /dev/null
```
For GNU `bc`:
```
real 53.85
user 39.50
sys 14.34
```
For this `bc`:
```
real 26.61
user 26.58
sys 0.03
```
It seems that both `bc`'s run `for` loops faster than `while` loops. I don't
know why my `bc` does that because both loops are using the same code underneath
the hood.
Note that, when running the benchmarks, the optimization used is not the one I
recommend, which is `-O3 -flto -march=native`. This `bc` separates its code into
modules that, when optimized at link time, removes a lot of the inefficiency
that comes from function overhead. This is most keenly felt with one function:
`bc_vec_item()`, which should just turn into one instruction (on `x86_64`) when
optimized at link time and inlined. There are other functions that matter as
well.
When compiling this `bc` with the recommended optimizations, the results are as
follows.
For the first script:
```
real 1.88
user 1.88
sys 0.00
```
For the second script:
```
real 19.43
user 19.43
sys 0.00
```
For the third script:
```
real 20.58
user 20.53
sys 0.03
```
This is more competitive.
In addition, when compiling with the above recommendation, this `bc` gets even
faster when doing math.
[1]: https://github.com/torvalds/linux/blob/master/kernel/time/timeconst.bc