|
|
|
# Benchmarks
|
|
|
|
|
|
|
|
These are the results of benchmarks comparing this `bc` (at version `2.7.0`) and
|
|
|
|
GNU `bc` (at version `1.07.1`), both compiled with `clang 9` at `-O2`.
|
|
|
|
|
|
|
|
Note: all benchmarks were run four times, and the fastest run is the one shown.
|
|
|
|
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 1 0 1 1 [bc]
|
|
|
|
```
|
|
|
|
|
|
|
|
For GNU `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 2.06
|
|
|
|
user 1.11
|
|
|
|
sys 0.95
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 0.98
|
|
|
|
user 0.95
|
|
|
|
sys 0.02
|
|
|
|
```
|
|
|
|
|
|
|
|
### Subtraction
|
|
|
|
|
|
|
|
The command used was:
|
|
|
|
|
|
|
|
```
|
|
|
|
tests/script.sh bc subtract.bc 1 0 1 1 [bc]
|
|
|
|
```
|
|
|
|
|
|
|
|
For GNU `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 2.04
|
|
|
|
user 1.04
|
|
|
|
sys 0.99
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 1.02
|
|
|
|
user 1.00
|
|
|
|
sys 0.01
|
|
|
|
```
|
|
|
|
|
|
|
|
### Multiplication
|
|
|
|
|
|
|
|
The command used was:
|
|
|
|
|
|
|
|
```
|
|
|
|
tests/script.sh bc multiply.bc 1 0 1 1 [bc]
|
|
|
|
```
|
|
|
|
|
|
|
|
For GNU `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 5.96
|
|
|
|
user 4.27
|
|
|
|
sys 1.68
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 2.15
|
|
|
|
user 2.11
|
|
|
|
sys 0.04
|
|
|
|
```
|
|
|
|
|
|
|
|
### Division
|
|
|
|
|
|
|
|
The command used was:
|
|
|
|
|
|
|
|
```
|
|
|
|
tests/script.sh bc divide.bc 1 0 1 1 [bc]
|
|
|
|
```
|
|
|
|
|
|
|
|
For GNU `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 2.74
|
|
|
|
user 1.84
|
|
|
|
sys 0.89
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 1.49
|
|
|
|
user 1.48
|
|
|
|
sys 0.00
|
|
|
|
```
|
|
|
|
|
|
|
|
### Power
|
|
|
|
|
|
|
|
The command used was:
|
|
|
|
|
|
|
|
```
|
|
|
|
printf '1234567890^100000; halt\n' | time -p [bc] -lq > /dev/null
|
|
|
|
```
|
|
|
|
|
|
|
|
For GNU `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 9.60
|
|
|
|
user 9.58
|
|
|
|
sys 0.01
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 0.67
|
|
|
|
user 0.66
|
|
|
|
sys 0.00
|
|
|
|
```
|
|
|
|
|
|
|
|
### Scripts
|
|
|
|
|
|
|
|
[This file][1] was downloaded, saved at `../timeconst.bc` and the following
|
|
|
|
patch was applied:
|
|
|
|
|
|
|
|
```
|
|
|
|
--- ../timeconst.bc 2018-09-28 11:32:22.808669000 -0600
|
|
|
|
+++ ../timeconst.bc 2019-06-07 07:26:36.359913078 -0600
|
|
|
|
@@ -110,8 +110,10 @@
|
|
|
|
|
|
|
|
print "#endif /* KERNEL_TIMECONST_H */\n"
|
|
|
|
}
|
|
|
|
- halt
|
|
|
|
}
|
|
|
|
|
|
|
|
-hz = read();
|
|
|
|
-timeconst(hz)
|
|
|
|
+for (i = 0; i <= 50000; ++i) {
|
|
|
|
+ timeconst(i)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+halt
|
|
|
|
```
|
|
|
|
|
|
|
|
The command used was:
|
|
|
|
|
|
|
|
```
|
|
|
|
time -p [bc] ../timeconst.bc > /dev/null
|
|
|
|
```
|
|
|
|
|
|
|
|
For GNU `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 15.26
|
|
|
|
user 14.60
|
|
|
|
sys 0.64
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 11.24
|
|
|
|
user 11.23
|
|
|
|
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 14.89
|
|
|
|
user 14.88
|
|
|
|
sys 0.00
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 22.19
|
|
|
|
user 22.18
|
|
|
|
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 42.92
|
|
|
|
user 32.70
|
|
|
|
sys 10.19
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 28.50
|
|
|
|
user 28.44
|
|
|
|
sys 0.02
|
|
|
|
```
|
|
|
|
|
|
|
|
I have no idea why the performance of both `bc`'s fell off a cliff, especially
|
|
|
|
the dismal showing by the GNU `bc`.
|
|
|
|
|
|
|
|
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 turn into just one instruction (on `x86_64`) when
|
|
|
|
optimized at link time and inlined. There are other functions that matter as
|
|
|
|
well.
|
|
|
|
|
|
|
|
When compiling both `bc`'s with the recommended optimizations, the results are
|
|
|
|
as follows.
|
|
|
|
|
|
|
|
For the first script, the command was:
|
|
|
|
|
|
|
|
```
|
|
|
|
time -p [bc] ../timeconst.bc > /dev/null
|
|
|
|
```
|
|
|
|
|
|
|
|
For GNU `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 14.01
|
|
|
|
user 13.41
|
|
|
|
sys 0.59
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 9.40
|
|
|
|
user 9.39
|
|
|
|
sys 0.00
|
|
|
|
```
|
|
|
|
|
|
|
|
For the second script, the command was:
|
|
|
|
|
|
|
|
```
|
|
|
|
time -p [bc] ../test.bc > /dev/null
|
|
|
|
```
|
|
|
|
|
|
|
|
For GNU `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 12.58
|
|
|
|
user 12.58
|
|
|
|
sys 0.00
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 17.99
|
|
|
|
user 17.98
|
|
|
|
sys 0.00
|
|
|
|
```
|
|
|
|
|
|
|
|
For the third script, the command was:
|
|
|
|
|
|
|
|
```
|
|
|
|
time -p [bc] ../test2.bc > /dev/null
|
|
|
|
```
|
|
|
|
|
|
|
|
For GNU `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 39.74
|
|
|
|
user 27.28
|
|
|
|
sys 12.44
|
|
|
|
```
|
|
|
|
|
|
|
|
For this `bc`:
|
|
|
|
|
|
|
|
```
|
|
|
|
real 23.31
|
|
|
|
user 23.27
|
|
|
|
sys 0.02
|
|
|
|
```
|
|
|
|
|
|
|
|
This is more competitive.
|
|
|
|
|
|
|
|
In addition, when compiling with the above recommendation, this `bc` gets even
|
|
|
|
faster when doing math.
|
|
|
|
|
|
|
|
### Recommended Compiler
|
|
|
|
|
|
|
|
When I ran these benchmarks with my `bc` compiled under `clang` vs. `gcc`, it
|
|
|
|
performed much better under `clang`. I recommend compiling this `bc` with
|
|
|
|
`clang`.
|
|
|
|
|
|
|
|
[1]: https://github.com/torvalds/linux/blob/master/kernel/time/timeconst.bc
|