initial import
Mon May 25 16:59:32 CEST 2009 Tobias Rautenkranz <tobias@rautenkranz.ch>
* initial import
diff -rN -u old-benchmark/CMakeLists.txt new-benchmark/CMakeLists.txt
--- old-benchmark/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/CMakeLists.txt 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,12 @@
+find_package(Qt4)
+set(QT_DONT_USE_QTGUI true)
+include(${QT_USE_FILE})
+
+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)
+target_link_libraries(cl-smoke-benchmark ${QT_LIBRARIES})
diff -rN -u old-benchmark/benchmark.cpp new-benchmark/benchmark.cpp
--- old-benchmark/benchmark.cpp 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/benchmark.cpp 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,19 @@
+#include "benchmark.h"
+
+#include <QByteArray>
+
+static QByteArray array("foobar");
+
+extern "C" {
+
+CL_SMOKE_BENCHMARK_EXPORT char
+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;
+}
+
+} // extern "C"
diff -rN -u old-benchmark/benchmark.lisp new-benchmark/benchmark.lisp
--- old-benchmark/benchmark.lisp 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/benchmark.lisp 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,53 @@
+(in-package :cl-smoke.benchmark)
+
+(defun timing (function &rest arguments)
+ (let ((timings))
+ (apply #'sb-ext:call-with-timing
+ #'(lambda (&rest args)
+ (setf timings args))
+ function
+ arguments)
+ (list :processor-cycles (getf timings :processor-cycles))))
+
+(defun print-header (stream data)
+ (dolist (d (alexandria:plist-alist (first data)))
+ (format stream "~A " (first d)))
+ (format stream "~%"))
+
+(defun write-R-table (data file)
+ (with-open-file (out file :direction :output)
+ (print-header out data)
+ (dolist (d data)
+ (dolist (e (alexandria:plist-alist d))
+ (format out "~S~T" (rest e)))
+ (format out "~%"))))
+
+
+(defun benchmark (function &rest args)
+ (let ((data))
+ (dotimes (n 20 data)
+ (sb-ext:gc :full t)
+ (push (apply #'timing function args)
+ data))))
+
+(defun run-compare (name function cxx-function iterations)
+ (let ((data (benchmark function iterations))
+ (cxx-data (benchmark cxx-function iterations))
+ (file (make-pathname :defaults name
+ :type "dat")))
+ (write-R-table data file)
+ (write-R-table cxx-data
+ (make-pathname :defaults file
+ :name (concatenate 'string
+ "cxx-"
+ (pathname-name file))))))
+
+(defun run ()
+ (run-compare "overload" #'overload #'cl-smoke-benchmark-overload 1000)
+ (run-compare "inline-call" #'inline-call
+ #'cl-smoke-benchmark-byte-array-size 1000)
+ (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)))
diff -rN -u old-benchmark/benchmark.sh new-benchmark/benchmark.sh
--- old-benchmark/benchmark.sh 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/benchmark.sh 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +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
diff -rN -u old-benchmark/cl-smoke.benchmark.mbd new-benchmark/cl-smoke.benchmark.mbd
--- old-benchmark/cl-smoke.benchmark.mbd 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/cl-smoke.benchmark.mbd 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,33 @@
+;;;; -*- Mode: lisp; indent-tabs-mode: nil -*-
+
+
+;;; SYSDEF.CMAKE
+(defpackage :sysdef.cmake
+ (:use :cl :sysdef)
+ (:export :cmake-file :cmake-library))
+
+(in-package :sysdef.cmake)
+(defclass sysdef.cmake:cmake-file (source-file)
+ ()
+ (:default-initargs :type "txt"))
+
+(defclass sysdef.cmake:cmake-library (component)
+ ())
+;;; end SYSDEF.CMAKE
+
+(in-package :sysdef-user)
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (use-package :sysdef.cmake))
+
+(define-system :cl-smoke.benchmark ()
+ (:version 0 0 1)
+ (:documentation "Benchmark cl-smoke agains C++."
+ (:serial t)
+ (:components
+ "package"
+ ("CMakeLists" sysdef.cmake:cmake-file)
+ ("libcl-smoke-benchmark" sysdef.cmake:cmake-library)
+ "cxx"
+ "lisp-benchmark"
+ "benchmark")
+ (:needs :qt :cffi :sysdef.cmake))
diff -rN -u old-benchmark/construct.cpp new-benchmark/construct.cpp
--- old-benchmark/construct.cpp 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/construct.cpp 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,36 @@
+#include "benchmark.h"
+
+#include <QObject>
+#include <QVector>
+
+static QVector<QObject*> a;
+
+extern "C" {
+
+CL_SMOKE_BENCHMARK_EXPORT void
+cl_smoke_benchmark_construct_setup(size_t iterations)
+{
+ a.resize(iterations);
+}
+
+CL_SMOKE_BENCHMARK_EXPORT char
+cl_smoke_benchmark_construct(size_t iterations)
+{
+ Q_ASSERT(a.size() == iterations);
+
+ for (size_t i=0; i<iterations; i++)
+ a[i] = new QObject();
+}
+
+CL_SMOKE_BENCHMARK_EXPORT void
+cl_smoke_benchmark_construct_cleanup(size_t iterations)
+{
+ Q_ASSERT(a.size() == iterations);
+
+ for (size_t i=0; i<iterations; i++)
+ delete a[i];
+
+ a.clear();
+}
+
+}
diff -rN -u old-benchmark/cxx.lisp new-benchmark/cxx.lisp
--- old-benchmark/cxx.lisp 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/cxx.lisp 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,31 @@
+(in-package :cl-smoke.benchmark)
+
+(use-foreign-library libcl-smoke-benchmark)
+(defctype size-t :unsigned-int)
+
+(defcfun cl-smoke-benchmark-byte-array-size :char
+ (iterations size-t))
+
+(defcfun cl-smoke-benchmark-overload :unsigned-int
+ (iterations size-t))
+
+
+(defcfun cl-smoke-benchmark-construct-setup :void
+ (iterations size-t))
+
+(defcfun cl-smoke-benchmark-construct :char
+ (iterations size-t))
+
+(defcfun cl-smoke-benchmark-construct-cleanup :void
+ (iterations size-t))
+
+
+(defmacro with-benchmark-cxx-construct ((iterations) &body body)
+ `(progn
+ (cl-smoke-benchmark-construct-setup ,iterations)
+ ,@body
+ (cl-smoke-benchmark-construct-cleanup ,iterations)))
+
+
+(defcfun cl-smoke-benchmark-simple-call :void
+ (iterations size-t))
diff -rN -u old-benchmark/lisp-benchmark.lisp new-benchmark/lisp-benchmark.lisp
--- old-benchmark/lisp-benchmark.lisp 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/lisp-benchmark.lisp 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,38 @@
+(in-package :cl-smoke.benchmark)
+
+(let ((array (make-instance 'qt:byte-array :args '("foobar"))))
+ (defun inline-call (iterations)
+ (declare (fixnum iterations)
+ (optimize (speed 3)))
+ (let ((char #\Null))
+ (declare (character char))
+ (dotimes (i iterations char)
+ (setf char (cxx:aref array 0))))))
+
+(let ((object (make-instance 'qt:object)))
+ (defun simple-call (iterations)
+ (declare (fixnum iterations)
+ (optimize (speed 3)))
+ (dotimes (i iterations)
+ (cxx:kill-timer object 0))))
+
+(defclass my-object (qt:object)
+ ()
+ (:metaclass cxx:class))
+
+(defmethod cxx:meta-object ((object my-object))
+ (declare (optimize (speed 3)))
+ nil)
+
+(defun overload (iterations)
+ (declare (fixnum iterations)
+ (optimize (speed 3)))
+ (let ((object (make-instance 'my-object)))
+ (dotimes (i iterations)
+ (cxx:meta-object object))))
+
+(defun construct (iterations)
+ (declare (fixnum iterations)
+ (optimize (speed 3)))
+ (dotimes (i iterations)
+ (make-instance 'qt:object)))
diff -rN -u old-benchmark/overload.cpp new-benchmark/overload.cpp
--- old-benchmark/overload.cpp 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/overload.cpp 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,29 @@
+#include "benchmark.h"
+
+#include <QObject>
+#include <QMetaObject>
+
+class my_object : public QObject
+{
+ public:
+ virtual const QMetaObject*
+ metaObject() const
+ { return NULL; }
+};
+
+extern "C" {
+
+CL_SMOKE_BENCHMARK_EXPORT unsigned
+cl_smoke_benchmark_overload(size_t iterations)
+{
+ my_object object;
+ QObject& o = object;
+ unsigned m = 0;
+
+ for (size_t i=0; i<iterations; i++)
+ m += reinterpret_cast<unsigned>(o.metaObject());
+
+ return m;
+}
+
+} // extern "C"
diff -rN -u old-benchmark/package.lisp new-benchmark/package.lisp
--- old-benchmark/package.lisp 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/package.lisp 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,2 @@
+(defpackage :cl-smoke.benchmark
+ (:use :cl :cxx-support :cffi))
diff -rN -u old-benchmark/plot.R new-benchmark/plot.R
--- old-benchmark/plot.R 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/plot.R 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,31 @@
+#!/usr/bin/R
+
+
+boxplot_benchmark <- function(lisp_data, cxx_data) {
+ cxx_mean <- mean(cxx_data$PROCESSOR.CYCLES)
+ boxplot(c(cxx_data["PROCESSOR.CYCLES"]/cxx_mean, lisp_data["PROCESSOR.CYCLES"]/cxx_mean),
+ log="y", names=c("C++", "Lisp"), ylab="processor cycles")
+}
+
+pdf("benchmark.pdf")
+
+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")
+
+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")
diff -rN -u old-benchmark/simple-call.cpp new-benchmark/simple-call.cpp
--- old-benchmark/simple-call.cpp 1970-01-01 01:00:00.000000000 +0100
+++ new-benchmark/simple-call.cpp 2014-10-30 06:54:02.000000000 +0100
@@ -0,0 +1,16 @@
+#include "benchmark.h"
+
+#include <QObject>
+
+static QObject object;
+
+extern "C" {
+
+CL_SMOKE_BENCHMARK_EXPORT void
+cl_smoke_benchmark_simple_call(size_t iterations)
+{
+ for (size_t i=0; i<iterations; i++)
+ object.killTimer(0);
+}
+
+} // extern "C"