Skip to content

Commit f85f2ae

Browse files
committed
Added class registration benchmarking scripts
There scripts were used to test the class template compiler impact for the class template options change. I'm committing them because they might well be a useful base for similar compilation impacts of future features.
1 parent 6b52c83 commit f85f2ae

File tree

7 files changed

+239
-0
lines changed

7 files changed

+239
-0
lines changed

tools/bench/bench-common.sh

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
2+
DEFAULT_CXX=""
3+
4+
kern="`uname -s`"
5+
if which g++ >/dev/null; then
6+
if [ "$kern" = "Darwin" ]; then
7+
# Don't include g++ on Darwin by default unless it really is g++; the
8+
# default isn't really g++, it's a wrapper around an LLVM backend.
9+
# Real g++ has --version output starting with 'g++'
10+
if g++ --version | head -n 1 | grep -q '^g++'; then
11+
DEFAULT_CXX="$DEFAULT_CXX g++"
12+
fi
13+
else
14+
DEFAULT_CXX="$DEFAULT_CXX g++"
15+
fi
16+
fi
17+
18+
if which clang++ >/dev/null; then
19+
DEFAULT_CXX="$DEFAULT_CXX clang++"
20+
fi
21+
22+
23+
CXXS="${CXX:-$DEFAULT_CXX}"
24+
25+
python_flags="$(
26+
for pycfg in python3-config python-config python2-config; do
27+
if which $pycfg >/dev/null; then
28+
$pycfg --includes
29+
$pycfg --ldflags
30+
break
31+
fi
32+
done | tr '\n' ' ')"
33+
34+
CXXFLAGS="${CXXFLAGS:--Iinclude $python_flags -O2 -DNDEBUG -fPIC -std=c++14 -flto -fvisibility=hidden -Wall -Wextra -Wconversion}"
35+
36+
branch="`git rev-parse --abbrev-ref HEAD`"
37+
commit="`git rev-parse --short HEAD`"
38+
39+
gnutime=
40+
if [ "`uname -s`" = "Linux" ] && which time >/dev/null; then
41+
gnutime=1
42+
fi
43+
44+
time_command() {
45+
if [ -n "$gnutime" ]; then
46+
# Use system `time` on linux to also report max RSS, which bash's built-in can't do
47+
\time --format='%U user, %e elapsed, %Mk max' "$@"
48+
else
49+
TIMEFORMAT="%U user, %E elapsed"
50+
time "$@"
51+
fi
52+
}
53+
54+
55+
master=
56+
if [ "$branch" = "upstream" ] || [ "$branch" = "master" ]; then master=1; fi
57+
58+
pad() {
59+
printf "%${1}s" "$2"
60+
}
61+
62+
show_compilers() {
63+
for CXX in $CXXS; do
64+
echo -n "$(pad 11 $CXX) is: "
65+
$CXX --version | head -n 1
66+
done
67+
}
68+
69+
70+
title() {
71+
echo -e "Benchmarking $1 on $branch ($commit)\n---"
72+
73+
show_compilers
74+
75+
echo
76+
}
77+

tools/bench/class-both.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
3+
set -e
4+
. `dirname $0`/class-common.sh
5+
6+
title "binding classes with default unique_ptr and trampoline specified"
7+
8+
9+
for CLASSES in ${COUNTS:-100 400 1000}; do
10+
(
11+
echo "#include <pybind11/pybind11.h>"
12+
for ((i = 0; i < CLASSES; i++)); do
13+
echo "class Class$i {}; class PyClass$i : public Class$i {};"
14+
done
15+
echo -e "PYBIND11_PLUGIN(test_$CLASSES) {
16+
namespace py = pybind11;
17+
py::module m(\"test_$CLASSES\");"
18+
for ((i = 0; i < CLASSES; i++)); do
19+
echo " py::class_<Class$i, std::unique_ptr<Class$i>, PyClass$i>(m, \"Class$i\");";
20+
done
21+
echo -e " return m.ptr();\n}"
22+
) >test_$CLASSES.cpp
23+
24+
compile test_$CLASSES.cpp
25+
26+
done

tools/bench/class-common.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
. `dirname $0`/bench-common.sh
3+
4+
if [ "$kern" = "Darwin" ]; then
5+
strip_args="-u -r"
6+
fi
7+
8+
compile() {
9+
set -e
10+
set -o pipefail
11+
SRC="$1"
12+
for CXX in $CXXS; do
13+
SO="${SRC%.*}_${CXX}.so"
14+
echo -n "$(pad 11 $CXX), $(pad 4 $CLASSES) classes compilation: "
15+
if ! time_command $CXX $CXXFLAGS -shared -o $SO $SRC \
16+
2>&1 | perl -ne '/ user, / and print s/\n//r'; then
17+
echo -e "Compilation failed, aborting. Tried to compile using:\n\n$CXX $CXXFLAGS -shared -o $SO $SRC\n"
18+
return 1
19+
fi
20+
21+
strip $strip_args $SO 2>/dev/null
22+
# stat's arguments vary across systems, so use perl to get so size
23+
echo ", $(perl -e 'print -s shift' $SO) bytes so"
24+
25+
done
26+
}

tools/bench/class-inherit.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/bash
2+
3+
set -e
4+
. `dirname $0`/class-common.sh
5+
6+
title "binding of parent/child class pairs"
7+
8+
9+
# Cut defaults in half here vs other scripts, because for each of these, we bind both a parent and child class:
10+
for CLASSES in ${COUNTS:-50 200 500}; do
11+
(
12+
echo "#include <pybind11/pybind11.h>"
13+
for ((i = 0; i < CLASSES; i++)); do
14+
echo "class BaseClass$i {}; class Class$i : public BaseClass$i {};"
15+
done
16+
echo -e "PYBIND11_PLUGIN(test_$CLASSES) {
17+
namespace py = pybind11;
18+
py::module m(\"test_$CLASSES\");"
19+
for ((i = 0; i < CLASSES; i++)); do
20+
echo " py::class_<BaseClass$i>(m, \"B$i\");"
21+
echo -n " py::class_<Class$i"
22+
if [ -n "$master" ]; then
23+
echo ">(m, \"C$i\", py::base<BaseClass$i>());"
24+
else
25+
echo ", BaseClass$i>(m, \"C$i\");"
26+
fi
27+
done
28+
echo -e " return m.ptr();\n}"
29+
) >test_$CLASSES.cpp
30+
31+
compile test_$CLASSES.cpp
32+
done

tools/bench/class-noargs.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
3+
set -e
4+
. `dirname $0`/class-common.sh
5+
6+
title "binding classes with no template args specified"
7+
8+
9+
for CLASSES in ${COUNTS:-100 400 1000}; do
10+
(
11+
echo "#include <pybind11/pybind11.h>"
12+
for ((i = 0; i < CLASSES; i++)); do
13+
echo "class Class$i {};"
14+
done
15+
echo -e "PYBIND11_PLUGIN(test_$CLASSES) {
16+
namespace py = pybind11;
17+
py::module m(\"test_$CLASSES\");"
18+
for ((i = 0; i < CLASSES; i++)); do
19+
echo " py::class_<Class$i>(m, \"Class$i\");";
20+
done
21+
echo -e " return m.ptr();\n}"
22+
) >test_$CLASSES.cpp
23+
24+
compile test_$CLASSES.cpp
25+
done

tools/bench/class-shptr.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
3+
set -e
4+
. `dirname $0`/class-common.sh
5+
6+
title "binding classes with shared_ptr holder"
7+
8+
9+
for CLASSES in ${COUNTS:-100 400 1000}; do
10+
(
11+
echo "#include <pybind11/pybind11.h>"
12+
echo "PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>);"
13+
for ((i = 0; i < CLASSES; i++)); do
14+
echo "class Class$i {};"
15+
done
16+
echo -e "PYBIND11_PLUGIN(test_$CLASSES) {
17+
namespace py = pybind11;
18+
py::module m(\"test_$CLASSES\");"
19+
for ((i = 0; i < CLASSES; i++)); do
20+
echo " py::class_<Class$i, std::shared_ptr<Class$i>>(m, \"Class$i\");";
21+
done
22+
echo -e " return m.ptr();\n}"
23+
) >test_$CLASSES.cpp
24+
25+
compile test_$CLASSES.cpp
26+
done

tools/bench/class-tramp.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
3+
set -e
4+
. `dirname $0`/class-common.sh
5+
6+
title "binding classes with trampoline"
7+
8+
9+
for CLASSES in ${COUNTS:-100 400 1000}; do
10+
(
11+
echo "#include <pybind11/pybind11.h>"
12+
for ((i = 0; i < CLASSES; i++)); do
13+
echo "class Class$i {}; class PyClass$i : public Class$i {};"
14+
done
15+
echo -e "PYBIND11_PLUGIN(test_$CLASSES) {
16+
namespace py = pybind11;
17+
py::module m(\"test_$CLASSES\");"
18+
for ((i = 0; i < CLASSES; i++)); do
19+
echo -n " py::class_<Class$i"
20+
if [ -n "$master" ]; then echo -n ", std::unique_ptr<Class$i>"; fi
21+
echo ", PyClass$i>(m, \"Class$i\");";
22+
done
23+
echo -e " return m.ptr();\n}"
24+
) >test_$CLASSES.cpp
25+
26+
compile test_$CLASSES.cpp
27+
done

0 commit comments

Comments
 (0)