Skip to content

Commit 47a6ee7

Browse files
committed
add another binop benchmark
1 parent fe79f0c commit 47a6ee7

File tree

4 files changed

+294
-0
lines changed

4 files changed

+294
-0
lines changed
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
code = """
41+
#include <Python.h>
42+
#include "structmember.h"
43+
44+
static PyTypeObject FloatSubclass;
45+
46+
static PyObject* new_fp(double val) {
47+
PyFloatObject* fp = PyObject_New(PyFloatObject, &FloatSubclass);
48+
fp->ob_fval = val;
49+
return (PyObject*)fp;
50+
}
51+
52+
static PyObject* fp_add(PyObject* l, PyObject* r) {
53+
if (PyFloat_Check(l)) {
54+
if (PyFloat_Check(r)) {
55+
return new_fp(PyFloat_AS_DOUBLE(l) + PyFloat_AS_DOUBLE(r));
56+
} else if (PyLong_Check(r)) {
57+
return new_fp(PyFloat_AS_DOUBLE(l) + PyLong_AsLong(r));
58+
}
59+
} else if (PyLong_Check(l)) {
60+
if (PyFloat_Check(r)) {
61+
return new_fp(PyLong_AsLong(l) + PyFloat_AS_DOUBLE(r));
62+
} else if (PyLong_Check(r)) {
63+
return new_fp(PyLong_AsLong(l) + PyLong_AsLong(r));
64+
}
65+
}
66+
return Py_NotImplemented;
67+
}
68+
69+
static PyObject* fp_mul(PyObject* l, PyObject* r) {
70+
if (PyFloat_Check(l)) {
71+
if (PyFloat_Check(r)) {
72+
return new_fp(PyFloat_AS_DOUBLE(l) * PyFloat_AS_DOUBLE(r));
73+
} else if (PyLong_Check(r)) {
74+
return new_fp(PyFloat_AS_DOUBLE(l) * PyLong_AsLong(r));
75+
}
76+
}
77+
return Py_NotImplemented;
78+
}
79+
80+
static PyObject* fp_div(PyObject* l, PyObject* r) {
81+
if (PyFloat_Check(l)) {
82+
if (PyFloat_Check(r)) {
83+
return new_fp(PyFloat_AS_DOUBLE(l) / PyFloat_AS_DOUBLE(r));
84+
} else if (PyLong_Check(r)) {
85+
return new_fp(PyFloat_AS_DOUBLE(l) / PyLong_AsLong(r));
86+
}
87+
}
88+
return Py_NotImplemented;
89+
}
90+
91+
static PyNumberMethods FloatSubclassMethods = {
92+
fp_add, // binaryfunc nb_add;
93+
0, // binaryfunc nb_subtract;
94+
fp_mul, // binaryfunc nb_multiply;
95+
0, // binaryfunc nb_remainder;
96+
0, // binaryfunc nb_divmod;
97+
0, // ternaryfunc nb_power;
98+
0, // unaryfunc nb_negative;
99+
0, // unaryfunc nb_positive;
100+
0, // unaryfunc nb_absolute;
101+
0, // inquiry nb_bool;
102+
0, // unaryfunc nb_invert;
103+
0, // binaryfunc nb_lshift;
104+
0, // binaryfunc nb_rshift;
105+
0, // binaryfunc nb_and;
106+
0, // binaryfunc nb_xor;
107+
0, // binaryfunc nb_or;
108+
0, // unaryfunc nb_int;
109+
0, // void *nb_reserved;
110+
0, // unaryfunc nb_float;
111+
112+
0, // binaryfunc nb_inplace_add;
113+
0, // binaryfunc nb_inplace_subtract;
114+
0, // binaryfunc nb_inplace_multiply;
115+
0, // binaryfunc nb_inplace_remainder;
116+
0, // ternaryfunc nb_inplace_power;
117+
0, // binaryfunc nb_inplace_lshift;
118+
0, // binaryfunc nb_inplace_rshift;
119+
0, // binaryfunc nb_inplace_and;
120+
0, // binaryfunc nb_inplace_xor;
121+
0, // binaryfunc nb_inplace_or;
122+
123+
0, // binaryfunc nb_floor_divide;
124+
fp_div, // binaryfunc nb_true_divide;
125+
0, // binaryfunc nb_inplace_floor_divide;
126+
0, // binaryfunc nb_inplace_true_divide;
127+
128+
0, // unaryfunc nb_index;
129+
130+
0, // binaryfunc nb_matrix_multiply;
131+
0 // binaryfunc nb_inplace_matrix_multiply;
132+
};
133+
134+
static PyTypeObject FloatSubclass = {
135+
PyVarObject_HEAD_INIT(NULL, 0)
136+
"FloatSubclass", /* tp_name */
137+
sizeof(PyFloatObject), /* tp_basicsize */
138+
0, /* tp_itemsize */
139+
0, /* tp_dealloc */
140+
0, /* tp_print */
141+
0, /* tp_getattr */
142+
0, /* tp_setattr */
143+
0, /* tp_reserved */
144+
0, /* tp_repr */
145+
&FloatSubclassMethods, /* tp_as_number */
146+
0, /* tp_as_sequence */
147+
0, /* tp_as_mapping */
148+
0, /* tp_hash */
149+
0, /* tp_call */
150+
0, /* tp_str */
151+
0, /* tp_getattro */
152+
0, /* tp_setattro */
153+
0, /* tp_as_buffer */
154+
Py_TPFLAGS_DEFAULT |
155+
Py_TPFLAGS_BASETYPE, /* tp_flags */
156+
"", /* tp_doc */
157+
0, /* tp_traverse */
158+
0, /* tp_clear */
159+
0, /* tp_richcompare */
160+
0, /* tp_weaklistoffset */
161+
0, /* tp_iter */
162+
0, /* tp_iternext */
163+
0, /* tp_methods */
164+
0, /* tp_members */
165+
0, /* tp_getset */
166+
&PyFloat_Type, /* tp_base */
167+
0, /* tp_dict */
168+
0, /* tp_descr_get */
169+
0, /* tp_descr_set */
170+
0, /* tp_dictoffset */
171+
0, /* tp_init */
172+
0, /* tp_alloc */
173+
0, /* tp_new */
174+
};
175+
176+
static PyModuleDef module = {
177+
PyModuleDef_HEAD_INIT,
178+
"module",
179+
"",
180+
-1,
181+
NULL, NULL, NULL, NULL, NULL
182+
};
183+
184+
PyMODINIT_FUNC
185+
PyInit_c_arith_binop_module(void) {
186+
PyType_Ready(&FloatSubclass);
187+
PyObject* m = PyModule_Create(&module);
188+
Py_INCREF(&FloatSubclass);
189+
PyModule_AddObject(m, "FloatSubclass", (PyObject *)&FloatSubclass);
190+
return m;
191+
}
192+
"""
193+
194+
195+
ccompile("c_arith_binop_module", code)
196+
from c_arith_binop_module import FloatSubclass
197+
198+
199+
def docompute(num):
200+
for i in range(num):
201+
sum_ = FloatSubclass(0.0)
202+
j = FloatSubclass(0)
203+
while j < num:
204+
sum_ += ((i + j) * (i + j + 1) + i + 1)
205+
j += 1
206+
207+
return sum_, type(sum_)
208+
209+
210+
def measure(num):
211+
for run in range(num):
212+
sum_ = docompute(num * 2)
213+
print("sum", sum_)
214+
215+
216+
def __benchmark__(num=5):
217+
measure(num)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
class Foo(object):
41+
pass
42+
43+
44+
class Bar(Foo):
45+
pass
46+
47+
48+
def do_stuff(foo, bar, baz):
49+
for i in range(50000):
50+
type(foo)
51+
type(bar)
52+
type(baz)
53+
54+
return type(foo), type(bar), type(baz)
55+
56+
57+
def measure(num):
58+
for i in range(num):
59+
if i % 3 == 0:
60+
result = do_stuff(Foo(), Bar(), {})
61+
elif i % 3 == 1:
62+
result = do_stuff(Bar(), Foo(), {})
63+
else:
64+
result = do_stuff({}, Foo(), Bar())
65+
66+
print(result)
67+
68+
69+
def __benchmark__(num=5000):
70+
measure(num)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ abstract static class StrNode extends PythonUnaryBuiltinNode {
111111
String str(double self) {
112112
return PFloat.doubleToString(self);
113113
}
114+
115+
@Specialization(guards = "getFloat.isSubtype(object)", limit = "1")
116+
String doNativeFloat(PythonNativeObject object,
117+
@SuppressWarnings("unused") @Cached("nativeFloat()") FromNativeSubclassNode<Double> getFloat) {
118+
return PFloat.doubleToString(getFloat.execute(object));
119+
}
114120
}
115121

116122
@Builtin(name = __REPR__, fixedNumOfPositionalArgs = 1)

mx.graalpython/mx_graalpython_bench_param.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
'c-instantiation': ITER_10 + ['50000000'],
103103
'c-magic-bool': ITER_10 + ['100000000'],
104104
'c_arith-binop': ITER_25 + ['5'],
105+
'c_arith_binop_2': ITER_25 + ['50'],
105106
}
106107

107108

0 commit comments

Comments
 (0)