add signal-slot benchmark & better graphs
Fri Jun 19 17:31:27 CEST 2009 Tobias Rautenkranz <tobias@rautenkranz.ch>
* add signal-slot benchmark & better graphs
diff -rN -u old-benchmark/CMakeLists.txt new-benchmark/CMakeLists.txt
--- old-benchmark/CMakeLists.txt 2014-10-30 06:54:01.000000000 +0100
+++ new-benchmark/CMakeLists.txt 2014-10-30 06:54:01.000000000 +0100
@@ -2,11 +2,16 @@
set(QT_DONT_USE_QTGUI true)
include(${QT_USE_FILE})
+set(CXX_BENCHMARK_SOURCES
+ benchmark.cpp construct.cpp overload.cpp simple-call.cpp signal_slot.cpp)
+
+qt4_automoc(signal_slot.cpp)
+
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-fvisibility=hidden" CXX_VISIBILITY)
if(CXX_VISIBILITY)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden")
endif(CXX_VISIBILITY)
-add_library(cl-smoke-benchmark MODULE benchmark.cpp construct.cpp overload.cpp simple-call.cpp)
+add_library(cl-smoke-benchmark MODULE ${CXX_BENCHMARK_SOURCES})
target_link_libraries(cl-smoke-benchmark ${QT_LIBRARIES})
diff -rN -u old-benchmark/benchmark.cpp new-benchmark/benchmark.cpp
--- old-benchmark/benchmark.cpp 2014-10-30 06:54:01.000000000 +0100
+++ new-benchmark/benchmark.cpp 2014-10-30 06:54:01.000000000 +0100
@@ -6,14 +6,11 @@
extern "C" {
-CL_SMOKE_BENCHMARK_EXPORT char
+CL_SMOKE_BENCHMARK_EXPORT void
cl_smoke_benchmark_byte_array_size(size_t iterations)
{
- char a;
for(size_t i=0; i< iterations; i++)
- a += array.at(0);
-
- return a;
+ array.at(0);
}
} // extern "C"
diff -rN -u old-benchmark/benchmark.lisp new-benchmark/benchmark.lisp
--- old-benchmark/benchmark.lisp 2014-10-30 06:54:01.000000000 +0100
+++ new-benchmark/benchmark.lisp 2014-10-30 06:54:01.000000000 +0100
@@ -7,7 +7,9 @@
(setf timings args))
function
arguments)
- (list :processor-cycles (getf timings :processor-cycles))))
+ (list :processor-cycles (getf timings :processor-cycles)
+ :system-run-time-us (getf timings :system-run-time-us)
+ :user-run-time-us (getf timings :user-run-time-us))))
(defun print-header (stream data)
(dolist (d (alexandria:plist-alist (first data)))
@@ -22,17 +24,31 @@
(format out "~S~T" (rest e)))
(format out "~%"))))
+(defun write-lisp-info (file)
+ (write-R-table
+ `((:type ,(lisp-implementation-type)
+ :version ,(lisp-implementation-version)
+ :arch ,(machine-type)
+ :os ,(software-type)
+ :os-version ,(software-version)
+ :cl-smoke-version ,(mb.sysdef::version-string (mb.sysdef:version-of (mb.sysdef:find-system :smoke)))))
+ file))
-(defun benchmark (function &rest args)
+(defun benchmark (function iterations)
(let ((data))
+ (dotimes (n 3)
+ (funcall function iterations)) ;; startup
(dotimes (n 20 data)
(sb-ext:gc :full t)
- (push (apply #'timing function args)
+ (push (nconc (list :iterations iterations)
+ (timing function iterations))
data))))
-(defun run-compare (name function cxx-function iterations)
- (let ((data (benchmark function iterations))
- (cxx-data (benchmark cxx-function iterations))
+(defun run-compare (name function cxx-function iterations multiplier)
+ (format t "running ~A." name)
+ (let ((data (prog1 (benchmark function iterations) (princ ".")))
+ (cxx-data (prog1 (benchmark cxx-function (* multiplier iterations))
+ (princ ".")))
(file (make-pathname :defaults name
:type "dat")))
(write-R-table data file)
@@ -40,14 +56,18 @@
(make-pathname :defaults file
:name (concatenate 'string
"cxx-"
- (pathname-name file))))))
+ (pathname-name file)))))
+ (terpri))
-(defun run ()
- (run-compare "overload" #'overload #'cl-smoke-benchmark-overload 1000)
+(defun run (&optional construct)
+ (write-lisp-info "info.dat")
+ (run-compare "signal-slot" #'signal-slot
+ #'cl-smoke-benchmark-signal-slot 5000 1000)
(run-compare "inline-call" #'inline-call
- #'cl-smoke-benchmark-byte-array-size 1000)
+ #'cl-smoke-benchmark-byte-array-size 50000 3000)
(run-compare "simple-call" #'simple-call
- #'cl-smoke-benchmark-simple-call 1000)
- (with-benchmark-cxx-construct (1000)
- (run-compare "construct" #'construct
- #'cl-smoke-benchmark-construct 1000)))
+ #'cl-smoke-benchmark-simple-call 50000 3000)
+ (when construct
+ (with-benchmark-cxx-construct ((* 50 1000))
+ (run-compare "construct" #'construct
+ #'cl-smoke-benchmark-construct 1000 50))))
diff -rN -u old-benchmark/benchmark.sh new-benchmark/benchmark.sh
--- old-benchmark/benchmark.sh 2014-10-30 06:54:01.000000000 +0100
+++ new-benchmark/benchmark.sh 2014-10-30 06:54:01.000000000 +0100
@@ -1,5 +1,5 @@
#!/bin/sh
rm -- *.dat
-sbcl --eval "(mb:load :cl-smoke.benchmark)" --eval "(cl-smoke.benchmark::run)" --eval "(quit)" || exit 1
-R --no-save < ./plot.R
+sbcl --eval "(mb:load :cl-smoke.benchmark)" --eval "(cl-smoke.benchmark:run)" --eval "(quit)" || exit 1
+R --no-save < ./plot.R > /dev/null
diff -rN -u old-benchmark/cl-smoke.benchmark.mbd new-benchmark/cl-smoke.benchmark.mbd
--- old-benchmark/cl-smoke.benchmark.mbd 2014-10-30 06:54:01.000000000 +0100
+++ new-benchmark/cl-smoke.benchmark.mbd 2014-10-30 06:54:01.000000000 +0100
@@ -21,7 +21,7 @@
(define-system :cl-smoke.benchmark ()
(:version 0 0 1)
- (:documentation "Benchmark cl-smoke agains C++."
+ (:documentation "Benchmark cl-smoke agains C++.")
(:serial t)
(:components
"package"
diff -rN -u old-benchmark/cxx.lisp new-benchmark/cxx.lisp
--- old-benchmark/cxx.lisp 2014-10-30 06:54:01.000000000 +0100
+++ new-benchmark/cxx.lisp 2014-10-30 06:54:01.000000000 +0100
@@ -3,16 +3,22 @@
(use-foreign-library libcl-smoke-benchmark)
(defctype size-t :unsigned-int)
-(defcfun cl-smoke-benchmark-byte-array-size :char
+(declaim (inline cl-smoke-benchmark-byte-array-size))
+(defcfun cl-smoke-benchmark-byte-array-size :void
(iterations size-t))
+(declaim (inline cl-smoke-benchmark-overload))
(defcfun cl-smoke-benchmark-overload :unsigned-int
(iterations size-t))
+(declaim (inline cl-smoke-benchmark-signal-slot))
+(defcfun cl-smoke-benchmark-signal-slot :void
+ (iterations size-t))
(defcfun cl-smoke-benchmark-construct-setup :void
(iterations size-t))
+(declaim (inline cl-smoke-benchmark-construct))
(defcfun cl-smoke-benchmark-construct :char
(iterations size-t))
diff -rN -u old-benchmark/lisp-benchmark.lisp new-benchmark/lisp-benchmark.lisp
--- old-benchmark/lisp-benchmark.lisp 2014-10-30 06:54:01.000000000 +0100
+++ new-benchmark/lisp-benchmark.lisp 2014-10-30 06:54:01.000000000 +0100
@@ -10,6 +10,7 @@
(setf char (cxx:aref array 0))))))
(let ((object (make-instance 'qt:object)))
+ (declare (qt:object object))
(defun simple-call (iterations)
(declare (fixnum iterations)
(optimize (speed 3)))
@@ -20,16 +21,17 @@
()
(:metaclass cxx:class))
-(defmethod cxx:meta-object ((object my-object))
- (declare (optimize (speed 3)))
- nil)
-(defun overload (iterations)
+(defun signal-slot (iterations)
(declare (fixnum iterations)
(optimize (speed 3)))
- (let ((object (make-instance 'my-object)))
+ (let ((my-signal (make-instance 'cl-smoke.qt-impl::qsignal :argument-types nil)))
+ (declare (function my-signal))
+ (qt:connect my-signal
+ #'(lambda ()))
(dotimes (i iterations)
- (cxx:meta-object object))))
+ (funcall my-signal))))
+
(defun construct (iterations)
(declare (fixnum iterations)
diff -rN -u old-benchmark/package.lisp new-benchmark/package.lisp
--- old-benchmark/package.lisp 2014-10-30 06:54:01.000000000 +0100
+++ new-benchmark/package.lisp 2014-10-30 06:54:01.000000000 +0100
@@ -1,2 +1,3 @@
(defpackage :cl-smoke.benchmark
- (:use :cl :cxx-support :cffi))
+ (:use :cl :cxx-support :cffi)
+ (:export #:run))
diff -rN -u old-benchmark/plot.R new-benchmark/plot.R
--- old-benchmark/plot.R 2014-10-30 06:54:01.000000000 +0100
+++ new-benchmark/plot.R 2014-10-30 06:54:01.000000000 +0100
@@ -1,31 +1,52 @@
#!/usr/bin/R
+round_to_signif <- function(value, deviation) {
+ round(value, -floor(log(deviation)/log(10)))
+}
boxplot_benchmark <- function(lisp_data, cxx_data) {
+ iterations <- lisp_data$ITERATIONS[1]
+ cxx_iterations <- cxx_data$ITERATIONS[1]
+ cxx_multiplier <- iterations / cxx_iterations
+
cxx_mean <- mean(cxx_data$PROCESSOR.CYCLES)
- boxplot(c(cxx_data["PROCESSOR.CYCLES"]/cxx_mean, lisp_data["PROCESSOR.CYCLES"]/cxx_mean),
+ scaled_lisp_data <- lisp_data["PROCESSOR.CYCLES"]/cxx_mean/cxx_multiplier;
+ par(mfrow=c(1,2))
+ boxplot(c(cxx_data["PROCESSOR.CYCLES"]/cxx_mean, scaled_lisp_data),
log="y", names=c("C++", "Lisp"), ylab="processor cycles")
+ axis(4, at=c(round_to_signif(mean(scaled_lisp_data),
+ sd(scaled_lisp_data))))
+
+ cxx_mean <- mean(cxx_data$USER.RUN.TIME.US)
+ scaled_lisp_data <- lisp_data["USER.RUN.TIME.US"]/cxx_mean/cxx_multiplier;
+ boxplot(c(cxx_data["USER.RUN.TIME.US"]/cxx_mean, scaled_lisp_data),
+ log="y", names=c("C++", "Lisp"), ylab="user run time")
+ axis(4, at=c(round_to_signif(mean(scaled_lisp_data),
+ sd(scaled_lisp_data))))
+ par(mfrow=c(1,1))
}
-pdf("benchmark.pdf")
+pdf("benchmark.pdf", title="cl-smoke.benchmark")
+
+info <- read.table("info.dat", header=TRUE)
cxx_simple_call <- read.table("cxx-simple-call.dat", header=TRUE)
simple_call <- read.table("simple-call.dat", header=TRUE)
boxplot_benchmark(simple_call, cxx_simple_call)
-title("Simple Call")
+title("Simple Call",
+ paste(info$TYPE[1], info$VERSION[1], "on", info$OS[1], info$OS.VERSION[1]))
cxx_inline_call <- read.table("cxx-inline-call.dat", header=TRUE)
inline_call <- read.table("inline-call.dat", header=TRUE)
boxplot_benchmark(inline_call, cxx_inline_call)
title("Inline Call")
-cxx_overload <- read.table("cxx-overload.dat", header=TRUE)
-overload <- read.table("overload.dat", header=TRUE)
-boxplot_benchmark(overload, cxx_overload)
-title("Overload Virtual Function")
-
-
-cxx_construct <- read.table("cxx-construct.dat", header=TRUE)
-construct <- read.table("construct.dat", header=TRUE)
-boxplot_benchmark(construct, cxx_construct)
-title("Construct Class")
+cxx_signal_slot <- read.table("cxx-signal-slot.dat", header=TRUE)
+signal_slot <- read.table("signal-slot.dat", header=TRUE)
+boxplot_benchmark(signal_slot, cxx_signal_slot)
+title("Signal Slot")
+
+#cxx_construct <- read.table("cxx-construct.dat", header=TRUE)
+#construct <- read.table("construct.dat", header=TRUE)
+#boxplot_benchmark(construct, cxx_construct)
+#title("Construct Class")
diff -rN -u old-benchmark/signal_slot.cpp new-benchmark/signal_slot.cpp
--- old-benchmark/signal_slot.cpp 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/signal_slot.cpp 2014-10-30 06:54:01.000000000 +0100
@@ -0,0 +1,24 @@
+#include "signal_slot.h"
+#include "signal_slot.moc"
+
+#include "benchmark.h"
+
+void
+signal_object::my_slot()
+{
+}
+
+extern "C" {
+
+CL_SMOKE_BENCHMARK_EXPORT void
+cl_smoke_benchmark_signal_slot(size_t iterations)
+{
+ signal_object object;
+ bool ret = QObject::connect(&object, SIGNAL(my_signal()), &object, SLOT(my_slot()));
+ Q_ASSERT(ret);
+
+ for (size_t i=0; i<iterations; i++)
+ object.emit_my_signal();
+}
+
+} // extern "C"
diff -rN -u old-benchmark/signal_slot.h new-benchmark/signal_slot.h
--- old-benchmark/signal_slot.h 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/signal_slot.h 2014-10-30 06:54:01.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef CL_SMOKE_BENCHMARK_SIGNAL_SLOT_H
+#define CL_SMOKE_BENCHMARK_SIGNAL_SLOT_H
+
+#include <QObject>
+
+class signal_object : public QObject
+{
+ Q_OBJECT
+ public:
+ void
+ emit_my_signal()
+ { emit my_signal(); }
+
+ signals:
+ void
+ my_signal();
+
+ public slots:
+ void
+ my_slot();
+};
+
+#endif // CL_SMOKE_BENCHMARK_SIGNAL_SLOT_H