[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/beardbolt 7ff619c375 283/323: Add some benchmarks
From: |
ELPA Syncer |
Subject: |
[elpa] externals/beardbolt 7ff619c375 283/323: Add some benchmarks |
Date: |
Thu, 9 Mar 2023 10:58:41 -0500 (EST) |
branch: externals/beardbolt
commit 7ff619c3757824b6d592bd4d79625ed19b17a90f
Author: João Távora <joaotavora@gmail.com>
Commit: João Távora <joaotavora@gmail.com>
Add some benchmarks
---
Makefile | 5 ++
README.md | 101 ++++++++++++++++++++++++++++----
beardbolt-benchmark.el | 57 ++++++++++++++++++
starters/unordered-multimap-emplace.cpp | 28 +++++++++
starters/vector-emplace-back.cpp | 51 ++++++++++++++++
5 files changed, 229 insertions(+), 13 deletions(-)
diff --git a/Makefile b/Makefile
index ced3bd1655..aeb139d5d9 100644
--- a/Makefile
+++ b/Makefile
@@ -13,4 +13,9 @@ compile: $(ELCFILES)
clean:
find . -iname '*.elc' -exec rm {} \;
+benchmark: compile
+ $(EMACS) -Q -L . --batch -l beardbolt-benchmark
starters/slow-to-process.cpp
+ $(EMACS) -Q -L . --batch -l beardbolt-benchmark
starters/vector-emplace-back.cpp
+ $(EMACS) -Q -L . --batch -l beardbolt-benchmark
starters/unordered-multimap-emplace.cpp
+
.PHONY: all compile clean check
diff --git a/README.md b/README.md
index 3c3af416b4..9a7a9d03b5 100644
--- a/README.md
+++ b/README.md
@@ -1,43 +1,118 @@
+# Beardbolt
-# beardbolt
-
-An experimental fork of [rmsbolt](https://gitlab.com/jgkamat/rmsbolt),
+An experimental fork of [RMSbolt](https://gitlab.com/jgkamat/rmsbolt),
itself a supercharged implementation of [godbolt
compiler-explorer](https://github.com/mattgodbolt/compiler-explorer)
for Emacs.
-beardbolt tries to make it easy to see what your compiler is doing.
+Beardbolt tries to make it easy to see what your compiler is doing.
It does this by showing you the assembly output of a given source code
file. It also highlights which source code a given assembly block
corresponds to, and vice versa.
-### Why rmsbolt over beardbolt
+### Why RMSbolt over Beardbolt
-- Supports more languages/compilers. beardbolt only C++/C clang/gcc.
+- Supports more languages/compilers. Beardbolt only C++/C clang/gcc.
- Has good documentation and a proper API.
-- Supports more Emacs versions. beardbolt only 28+
+- Supports more Emacs versions. Beardbolt only 28+
- Support compile-commands.json
-### Why beardbolt over rmsbolt
+### Why Beardbolt over RMSbolt
- Doesn't require file to be saved.
-- Faster (2x) and more responsive (TODO: show benchmarks)
-- Less buggy (TODO: show actual rmsbolt problems)
+- 2-5x faster on typical files. See [here][#benchmarks])
+- Less buggy (TODO: show actual RMSbolt problems)
- Has rainbows.
-- Simpler code (half the LOC)
+- Simpler code (less than half the LOC, but )
### Installation
```sh
-cd /path/to/beardbolt-clone
+cd /path/to/beardbolt/clone
make
```
```lisp
-(add-to-list 'load-path "/path/to/beardbolt-clone")
+(add-to-list 'load-path "/path/to/beardbolt/clone")
(require 'beardbolt)
```
```
M-x beardbolt-starter
```
+
+<a name="benchmarks"></a>
+### Benchmarks vs RMSbolt
+
+First note that Beardbolt is highly hacky/experimental and may be
+providing incorrect results, in which case most/all of the following
+benchmarks/comparisons are probably invalid.
+
+Second, a word on what "fast" means: the performance metric to
+optimize is responsiveness. Both Beardbolt and RMSbolt continuously
+analyze the program to present a "live" view of its assembly output.
+The goal is not only to provide this service as quickly as possible,
+but also to intrude as little as possible in the user's editing.
+
+Both extensions work in a two-step fashion. Beardbolt tries to
+optimize step 2.
+
+1. The file is saved and partially compiled by an external program
+
+ This happens asynchronously. It might takes several seconds and
+ spin up your CPU, but it does not generally harm the UX inside
+ Emacs.
+
+2. Some Elisp processing takes place on the assembly output
+
+ This happens inside Emacs, and it's generally bad if it takes a
+ long time, because Emacs is single-threaded and has no easily
+ accessible asynchronous mechanisms for this type of work.
+
+#### Results
+
+To run the benchmarks, have both RMSbolt and Beardbolt clones
+side-by-side, then:
+
+```
+$ cd /path/to/beardbolt/clone
+$ EMACS=~/Source/Emacs/emacs/src/emacs make benchmark
+/home/capitaomorte/Source/Emacs/emacs/src/emacs -Q -L . --batch -l
beardbolt-benchmark starters/slow-to-process.cpp
+RMSbolt timings for slow-to-process.cpp
+ samples: (1.329s 1.316s 1.338s 1.345s 1.341s)
+ average: 1.334s
+Beardbolt timings for slow-to-process.cpp
+ samples: (0.324s 0.338s 0.334s 0.334s 0.342s)
+ average: 0.334s
+/home/capitaomorte/Source/Emacs/emacs/src/emacs -Q -L . --batch -l
beardbolt-benchmark starters/vector-emplace-back.cpp
+RMSbolt timings for vector-emplace-back.cpp
+ samples: (0.234s 0.223s 0.223s 0.240s 0.224s)
+ average: 0.229s
+Beardbolt timings for vector-emplace-back.cpp
+ samples: (0.086s 0.074s 0.073s 0.074s 0.089s)
+ average: 0.079s
+/home/capitaomorte/Source/Emacs/emacs/src/emacs -Q -L . --batch -l
beardbolt-benchmark starters/unordered-multimap-emplace.cpp
+RMSbolt timings for unordered-multimap-emplace.cpp
+ samples: (0.534s 0.523s 0.524s 0.523s 0.529s)
+ average: 0.527s
+Beardbolt timings for unordered-multimap-emplace.cpp
+ samples: (0.103s 0.123s 0.103s 0.102s 0.118s)
+ average: 0.110s
+```
+
+This ran `beardbolt-compile` and `rmsbolt-compile` 5 times on small
+two [cppreference.com][https://cppreference.com] examples
+([1][example1], [2][example2]) as well as a known "slow" file found in
+RMSbolt's bug tracker
+([here](https://gitlab.com/jgkamat/rmsbolt/-/issues/9)).
+
+I patched `rmsbolt.el` to generate slightly less useless (for our use
+case) debug information with `-g1` instead of `g`. This makes RMSbolt
+run faster than it normally would, but since Beardbolt also uses this
+optimization, it is important to make the benchmarks fair(er?).
+
+The results were obtained on my Thinkpad T480 running Emacs 29
+(without native compilation).
+
+[example1]: https://en.cppreference.com/w/cpp/container/vector/emplace_back
+[example2]:
https://en.cppreference.com/w/cpp/container/unordered_multimap/emplace
diff --git a/beardbolt-benchmark.el b/beardbolt-benchmark.el
new file mode 100644
index 0000000000..c5ea454753
--- /dev/null
+++ b/beardbolt-benchmark.el
@@ -0,0 +1,57 @@
+(require 'beardbolt)
+(require 'cl-lib)
+(require 'benchmark)
+
+(defvar beardbolt-benchmark-samples nil)
+(defvar beardbolt-benchmark-rmsbolt-samples nil)
+
+(advice-add (quote beardbolt--handle-finish-compile) :around
+ (lambda (oldfun &rest args)
+ (push (benchmark-elapse (apply oldfun args))
+ beardbolt-benchmark-samples)))
+
+(defun beardbolt-benchmark-beardbolt (repeats)
+ (cl-loop
+ repeat repeats
+ do (beardbolt-compile (beardbolt--get-lang))
+ (while (process-live-p
+ (get-buffer-process (beardbolt--compilation-buffer)))
+ (accept-process-output)))
+ (message "Beardbolt timings for %s\n samples: %s\n average: %.3fs"
+ (file-name-nondirectory buffer-file-name)
+ (mapcar (lambda (s) (format "%.3fs" s))
+ (reverse beardbolt-benchmark-samples))
+ (/ (cl-reduce #'+ beardbolt-benchmark-samples)
+ (length beardbolt-benchmark-samples) 1.0)))
+
+(defun beardbolt-benchmark-rmsbolt (repeats)
+ (add-to-list 'load-path (expand-file-name "../../rmsbolt" default-directory))
+ (cond ((require 'rmsbolt nil t)
+ (advice-add (quote rmsbolt--handle-finish-compile) :around
+ (lambda (oldfun &rest args)
+ (push (benchmark-elapse (apply oldfun args))
+ beardbolt-benchmark-rmsbolt-samples)))
+ (cl-loop
+ repeat repeats
+ do
+ (sit-for 0.2) ;; unconfuse RMSbolt state cleanup
+ (rmsbolt-compile)
+ (while (process-live-p
+ (get-buffer-process (get-buffer "*rmsbolt-compilation*")))
+ (accept-process-output)))
+ (message "RMSbolt timings for %s\n samples: %s\n average: %.3fs"
+ (file-name-nondirectory buffer-file-name)
+ (mapcar (lambda (s) (format "%.3fs" s)) (reverse
+
beardbolt-benchmark-rmsbolt-samples))
+ (/ (cl-reduce #'+ beardbolt-benchmark-rmsbolt-samples)
+ (length beardbolt-benchmark-rmsbolt-samples) 1.0)))
+ (t
+ (message "Can't find rmsbolt in load path %s" load-path))))
+
+(with-current-buffer (find-file (car argv))
+ (beardbolt-benchmark-rmsbolt 5)
+ (beardbolt-benchmark-beardbolt 5))
+
+
+
+
diff --git a/starters/unordered-multimap-emplace.cpp
b/starters/unordered-multimap-emplace.cpp
new file mode 100644
index 0000000000..a059875be1
--- /dev/null
+++ b/starters/unordered-multimap-emplace.cpp
@@ -0,0 +1,28 @@
+#include <iostream>
+#include <utility>
+#include <string>
+#include <unordered_map>
+
+int main()
+{
+ std::unordered_multimap<std::string, std::string> m;
+
+ // uses pair's move constructor
+ m.emplace(std::make_pair(std::string("a"), std::string("a")));
+
+ // uses pair's converting move constructor
+ m.emplace(std::make_pair("b", "abcd"));
+
+ // uses pair's template constructor
+ m.emplace("d", "ddd");
+
+ // uses pair's piecewise constructor
+ m.emplace(std::piecewise_construct,
+ std::forward_as_tuple("c"),
+ std::forward_as_tuple(10, 'c'));
+
+
+ for (const auto &p : m) {
+ std::cout << p.first << " => " << p.second << '\n';
+ }
+}
diff --git a/starters/vector-emplace-back.cpp b/starters/vector-emplace-back.cpp
new file mode 100644
index 0000000000..7ee548c05e
--- /dev/null
+++ b/starters/vector-emplace-back.cpp
@@ -0,0 +1,51 @@
+#include <vector>
+#include <string>
+#include <cassert>
+#include <iostream>
+
+struct President
+{
+ std::string name;
+ std::string country;
+ int year;
+
+ President(std::string p_name, std::string p_country, int p_year)
+ : name(std::move(p_name)), country(std::move(p_country)), year(p_year)
+ {
+ std::cout << "I am being constructed.\n";
+ }
+ President(President&& other)
+ : name(std::move(other.name)), country(std::move(other.country)),
year(other.year)
+ {
+ std::cout << "I am being moved.\n";
+ }
+ President& operator=(const President& other) = default;
+};
+
+int main()
+{
+ std::vector<President> elections;
+ std::cout << "emplace_back:\n";
+ auto& ref = elections.emplace_back("Nelson Mandela", "South Africa", 1994);
+ assert(ref.year == 1994 && "uses a reference to the created object (C++17)");
+
+ std::vector<President> reElections;
+ std::cout << "\npush_back:\n";
+ reElections.push_back(President("Franklin Delano Roosevelt", "the USA",
1936));
+
+ std::cout << "\nContents:\n";
+ for (President const& president: elections) {
+ std::cout << president.name << " was elected president of "
+ << president.country << " in " << president.year << ".\n";
+ }
+ for (President const& president: reElections) {
+ std::cout << president.name << " was re-elected president of "
+ << president.country << " in " << president.year << ".\n";
+ }
+}
+
+// Local Variables:
+// beardbolt-preserve-directives: t
+// beardbolt-preserve-labels: t
+// beardbolt-command: "g++ -O3"
+// End:
- [elpa] externals/beardbolt 1873e605ab 256/323: Remove unused test/test-helper.el, (continued)
- [elpa] externals/beardbolt 1873e605ab 256/323: Remove unused test/test-helper.el, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt ce91938102 261/323: Simplify management of bb--temp-dir, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 264b614805 264/323: * beardbolt.el (bb-compile): Better handling of hack-local-variables., ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt ed99686703 267/323: Handle TTYs with unknown background color, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 715f132d0e 263/323: Started rewriting. Too many changes to mention., ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 325327bc70 273/323: Use inhibit-modification-hooks when modifying buffer, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 5131185d13 272/323: Add a Makefile, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 9aba82b6cd 271/323: Update starter/test files, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt b6958c3e0a 277/323: * beardbolt.el: preserve-library-functions -> preserve-weak-symbols, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 2a11095c75 281/323: Rethink and simplify asm-processing algorithm, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 7ff619c375 283/323: Add some benchmarks,
ELPA Syncer <=
- [elpa] externals/beardbolt 11a19cfa66 282/323: Simplify line correspondence and overlay management, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt e18e3ee5ae 289/323: Support compile_commands.json, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 3b7a5bc85a 288/323: Simplify M-x beardbolt-starter. Less tmp directory cruft., ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 2e9abdbcbf 293/323: fixup README tweak, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 93778d8391 298/323: Don't try any window scrolling heroics on recompile, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 12e926f66b 300/323: Correct local variable section of benchmark file, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 782febee77 307/323: Add new option bb-execute and simplify more code, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 13c51a99e0 309/323: Rework window management again. Not more like godbolt, ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt 27f10327f3 308/323: Rework window management. Not a bad alternative., ELPA Syncer, 2023/03/09
- [elpa] externals/beardbolt f260a62397 312/323: Refactor some behaviour for easier language definition, ELPA Syncer, 2023/03/09