Construct CallUncompiledFunctionPosArgs

Performance Diagrams

Construct CallUncompiledFunctionPosArgs 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000CPython 2.7Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)16133928072.9230769230769257.0CPython 2.7108688497194.46153846153845337.6425967151097Nuitka (historic)107936965316.0338.7936810588031Nuitka (master)107937334437.53846153846143338.7931158797783Nuitka (develop)107937467559.0769230769231338.79291217026537Nuitka (factory)Construct CallUncompiledFunctionPosArgsTicks Construct CallUncompiledFunctionPosArgs 00100000001000000020000000200000003000000030000000400000004000000050000000500000006000000060000000700000007000000080000000800000009000000090000000100000000100000000110000000110000000120000000120000000130000000130000000140000000140000000150000000150000000CPython 3.5Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)15128386972.9230769230769257.0CPython 3.50194.46153846153845504.11538461538464Nuitka (historic)101009001316.0339.1217319759828Nuitka (master)101008019437.53846153846143339.1233360287433Nuitka (develop)101018870559.0769230769231339.105611409085Nuitka (factory)Construct CallUncompiledFunctionPosArgsTicks

Source Code with Construct

from __future__ import print_function

exec("""
def python_func(a,b,c,d,e,f):
    pass
""")

def calledRepeatedly():
    # This is supposed to make a call to a non-compiled function, which is
    # being optimized separately.
# construct_begin
    python_func("some", "random", "values", "to", "check", "call")
    python_func("some", "other", "values", "to", "check", "call")
    python_func("some", "new", "values", "to", "check", "call")
# construct_alternative



for x in xrange(50000):
    calledRepeatedly()

print("OK.")

Source Code without Construct

from __future__ import print_function

exec("""
def python_func(a,b,c,d,e,f):
    pass
""")

def calledRepeatedly():
    # This is supposed to make a call to a non-compiled function, which is
    # being optimized separately.
# construct_begin



# construct_alternative
    pass
# construct_end

for x in xrange(50000):
    calledRepeatedly()

print("OK.")

Context Diff of Source Code


Construct
Baseline
26 26
27 def calledRepeatedly(): 27 def calledRepeatedly():
28     # This is supposed to make a call to a non-compiled function, which is 28     # This is supposed to make a call to a non-compiled function, which is
29     # being optimized separately. 29     # being optimized separately.
30 # construct_begin 30 # construct_begin
n 31     python_func("some", "random", "values", "to", "check", "call") n
32     python_func("some", "other", "values", "to", "check", "call")
33     python_func("some", "new", "values", "to", "check", "call")
34 # construct_alternative
35 31
36 32
t t 33  
34 # construct_alternative
35     pass
36 # construct_end
37 37
38 for x in xrange(50000): 38 for x in xrange(50000):
39     calledRepeatedly() 39     calledRepeatedly()
40 40
41 print("OK.") 41 print("OK.")

Context Diff of Generated Code


Construct
Baseline
29 29
30 PyObject *module___main__; 30 PyObject *module___main__;
31 PyDictObject *moduledict___main__; 31 PyDictObject *moduledict___main__;
32 32
33 /* The module constants used, if any. */ 33 /* The module constants used, if any. */
n 34 static PyObject *const_str_plain_to; n
35 static PyObject *const_str_plain___package__; 34 static PyObject *const_str_plain___package__;
36 static PyObject *const_str_digest_40641b58ed6f61cc974b85218932eb8d; 35 static PyObject *const_str_digest_40641b58ed6f61cc974b85218932eb8d;
n 37 static PyObject *const_tuple_4cee4124c8df2995a8a82b981e580f5e_tuple; n
38 extern PyObject *const_int_pos_1; 36 extern PyObject *const_int_pos_1;
n 39 static PyObject *const_str_plain_values; n
40 extern PyObject *const_dict_empty; 37 extern PyObject *const_dict_empty;
41 extern PyObject *const_str_plain___file__; 38 extern PyObject *const_str_plain___file__;
n 42 static PyObject *const_str_plain_other; n
43 extern PyObject *const_int_0; 39 extern PyObject *const_int_0;
n 44 static PyObject *const_str_plain_check; n
45 static PyObject *const_xrange_0_50000; 40 static PyObject *const_xrange_0_50000;
46 extern PyObject *const_str_plain_print; 41 extern PyObject *const_str_plain_print;
n 47 static PyObject *const_str_plain_call; n
48 static PyObject *const_int_pos_50000; 42 static PyObject *const_int_pos_50000;
49 static PyObject *const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple; 43 static PyObject *const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple;
n 50 static PyObject *const_str_plain_random; n
51 static PyObject *const_str_digest_cff94df562de96b388fbdbf5d2f6d359; 44 static PyObject *const_str_digest_cff94df562de96b388fbdbf5d2f6d359;
52 static PyObject *const_str_plain_calledRepeatedly; 45 static PyObject *const_str_plain_calledRepeatedly;
53 static PyObject *const_str_angle_module; 46 static PyObject *const_str_angle_module;
54 static PyObject *const_str_plain_x; 47 static PyObject *const_str_plain_x;
55 extern PyObject *const_tuple_empty; 48 extern PyObject *const_tuple_empty;
56 static PyObject *const_str_digest_5ed1392909ad16e6227b8230f4582352; 49 static PyObject *const_str_digest_5ed1392909ad16e6227b8230f4582352;
n 57 static PyObject *const_str_plain_python_func; n
58 static PyObject *const_str_plain_some;
59 static PyObject *const_str_plain_new;
60 extern PyObject *const_str_plain___loader__; 50 extern PyObject *const_str_plain___loader__;
61 extern PyObject *const_str_plain___main__; 51 extern PyObject *const_str_plain___main__;
n 62 static PyObject *const_tuple_78e2f1ad354bdb7db1a0fda186168ee0_tuple; n
63 static PyObject *const_str_angle_string; 52 static PyObject *const_str_angle_string;
n 64 static PyObject *const_tuple_ca2f155a28955fc472d4376e2721d689_tuple; n
65 extern PyObject *const_str_plain___doc__; 53 extern PyObject *const_str_plain___doc__;
66 extern PyObject *const_str_plain___cached__; 54 extern PyObject *const_str_plain___cached__;
67 static PyObject *const_str_plain_exec; 55 static PyObject *const_str_plain_exec;
68 static PyObject *module_filename_obj; 56 static PyObject *module_filename_obj;
69 57
70 static bool constants_created = false; 58 static bool constants_created = false;
71 59
72 static void createModuleConstants( void ) 60 static void createModuleConstants( void )
73 { 61 {
n 74     const_str_plain_to = UNSTREAM_STRING( &constant_bin[ 0 ], 2, 1 ); n
75     const_str_plain___package__ = UNSTREAM_STRING( &constant_bin[ 2 ], 11, 1 ); 62     const_str_plain___package__ = UNSTREAM_STRING( &constant_bin[ 0 ], 11, 1 );
76     const_str_digest_40641b58ed6f61cc974b85218932eb8d = UNSTREAM_STRING( &constant_bin[ 13 ], 40, 0 ); 63     const_str_digest_40641b58ed6f61cc974b85218932eb8d = UNSTREAM_STRING( &constant_bin[ 11 ], 40, 0 );
77     const_tuple_4cee4124c8df2995a8a82b981e580f5e_tuple = PyTuple_New( 6 );
78     const_str_plain_some = UNSTREAM_STRING( &constant_bin[ 53 ], 4, 1 );
79     PyTuple_SET_ITEM( const_tuple_4cee4124c8df2995a8a82b981e580f5e_tuple, 0, const_str_plain_some ); Py_INCREF( const_str_plain_some );
80     const_str_plain_new = UNSTREAM_STRING( &constant_bin[ 57 ], 3, 1 );
81     PyTuple_SET_ITEM( const_tuple_4cee4124c8df2995a8a82b981e580f5e_tuple, 1, const_str_plain_new ); Py_INCREF( const_str_plain_new );
82     const_str_plain_values = UNSTREAM_STRING( &constant_bin[ 60 ], 6, 1 );
83     PyTuple_SET_ITEM( const_tuple_4cee4124c8df2995a8a82b981e580f5e_tuple, 2, const_str_plain_values ); Py_INCREF( const_str_plain_values );
84     PyTuple_SET_ITEM( const_tuple_4cee4124c8df2995a8a82b981e580f5e_tuple, 3, const_str_plain_to ); Py_INCREF( const_str_plain_to );
85     const_str_plain_check = UNSTREAM_STRING( &constant_bin[ 66 ], 5, 1 );
86     PyTuple_SET_ITEM( const_tuple_4cee4124c8df2995a8a82b981e580f5e_tuple, 4, const_str_plain_check ); Py_INCREF( const_str_plain_check );
87     const_str_plain_call = UNSTREAM_STRING( &constant_bin[ 71 ], 4, 1 );
88     PyTuple_SET_ITEM( const_tuple_4cee4124c8df2995a8a82b981e580f5e_tuple, 5, const_str_plain_call ); Py_INCREF( const_str_plain_call );
89     const_str_plain_other = UNSTREAM_STRING( &constant_bin[ 75 ], 5, 1 );
90     const_int_pos_50000 = PyLong_FromUnsignedLong( 50000ul ); 64     const_int_pos_50000 = PyLong_FromUnsignedLong( 50000ul );
91     const_xrange_0_50000 = BUILTIN_XRANGE3( const_int_0, const_int_pos_50000, const_int_pos_1 ); 65     const_xrange_0_50000 = BUILTIN_XRANGE3( const_int_0, const_int_pos_50000, const_int_pos_1 );
92     const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple = PyTuple_New( 1 ); 66     const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple = PyTuple_New( 1 );
n 93     const_str_digest_5ed1392909ad16e6227b8230f4582352 = UNSTREAM_STRING( &constant_bin[ 80 ], 3, 0 ); n 67     const_str_digest_5ed1392909ad16e6227b8230f4582352 = UNSTREAM_STRING( &constant_bin[ 51 ], 3, 0 );
94     PyTuple_SET_ITEM( const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple, 0, const_str_digest_5ed1392909ad16e6227b8230f4582352 ); Py_INCREF( const_str_digest_5ed1392909ad16e6227b8230f4582352 ); 68     PyTuple_SET_ITEM( const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple, 0, const_str_digest_5ed1392909ad16e6227b8230f4582352 ); Py_INCREF( const_str_digest_5ed1392909ad16e6227b8230f4582352 );
n 95     const_str_plain_random = UNSTREAM_STRING( &constant_bin[ 83 ], 6, 1 ); n
96     const_str_digest_cff94df562de96b388fbdbf5d2f6d359 = UNSTREAM_STRING( &constant_bin[ 89 ], 87, 0 ); 69     const_str_digest_cff94df562de96b388fbdbf5d2f6d359 = UNSTREAM_STRING( &constant_bin[ 54 ], 87, 0 );
97     const_str_plain_calledRepeatedly = UNSTREAM_STRING( &constant_bin[ 176 ], 16, 1 ); 70     const_str_plain_calledRepeatedly = UNSTREAM_STRING( &constant_bin[ 141 ], 16, 1 );
98     const_str_angle_module = UNSTREAM_STRING( &constant_bin[ 192 ], 8, 0 ); 71     const_str_angle_module = UNSTREAM_STRING( &constant_bin[ 157 ], 8, 0 );
99     const_str_plain_x = UNSTREAM_STRING( &constant_bin[ 114 ], 1, 1 ); 72     const_str_plain_x = UNSTREAM_STRING( &constant_bin[ 79 ], 1, 1 );
100     const_str_plain_python_func = UNSTREAM_STRING( &constant_bin[ 18 ], 11, 1 );
101     const_tuple_78e2f1ad354bdb7db1a0fda186168ee0_tuple = PyTuple_New( 6 );
102     PyTuple_SET_ITEM( const_tuple_78e2f1ad354bdb7db1a0fda186168ee0_tuple, 0, const_str_plain_some ); Py_INCREF( const_str_plain_some );
103     PyTuple_SET_ITEM( const_tuple_78e2f1ad354bdb7db1a0fda186168ee0_tuple, 1, const_str_plain_random ); Py_INCREF( const_str_plain_random );
104     PyTuple_SET_ITEM( const_tuple_78e2f1ad354bdb7db1a0fda186168ee0_tuple, 2, const_str_plain_values ); Py_INCREF( const_str_plain_values );
105     PyTuple_SET_ITEM( const_tuple_78e2f1ad354bdb7db1a0fda186168ee0_tuple, 3, const_str_plain_to ); Py_INCREF( const_str_plain_to );
106     PyTuple_SET_ITEM( const_tuple_78e2f1ad354bdb7db1a0fda186168ee0_tuple, 4, const_str_plain_check ); Py_INCREF( const_str_plain_check );
107     PyTuple_SET_ITEM( const_tuple_78e2f1ad354bdb7db1a0fda186168ee0_tuple, 5, const_str_plain_call ); Py_INCREF( const_str_plain_call );
108     const_str_angle_string = UNSTREAM_STRING( &constant_bin[ 200 ], 8, 0 ); 73     const_str_angle_string = UNSTREAM_STRING( &constant_bin[ 165 ], 8, 0 );
109     const_tuple_ca2f155a28955fc472d4376e2721d689_tuple = PyTuple_New( 6 );
110     PyTuple_SET_ITEM( const_tuple_ca2f155a28955fc472d4376e2721d689_tuple, 0, const_str_plain_some ); Py_INCREF( const_str_plain_some );
111     PyTuple_SET_ITEM( const_tuple_ca2f155a28955fc472d4376e2721d689_tuple, 1, const_str_plain_other ); Py_INCREF( const_str_plain_other );
112     PyTuple_SET_ITEM( const_tuple_ca2f155a28955fc472d4376e2721d689_tuple, 2, const_str_plain_values ); Py_INCREF( const_str_plain_values );
113     PyTuple_SET_ITEM( const_tuple_ca2f155a28955fc472d4376e2721d689_tuple, 3, const_str_plain_to ); Py_INCREF( const_str_plain_to );
114     PyTuple_SET_ITEM( const_tuple_ca2f155a28955fc472d4376e2721d689_tuple, 4, const_str_plain_check ); Py_INCREF( const_str_plain_check );
115     PyTuple_SET_ITEM( const_tuple_ca2f155a28955fc472d4376e2721d689_tuple, 5, const_str_plain_call ); Py_INCREF( const_str_plain_call );
116     const_str_plain_exec = UNSTREAM_STRING( &constant_bin[ 208 ], 4, 1 ); 74     const_str_plain_exec = UNSTREAM_STRING( &constant_bin[ 173 ], 4, 1 );
117 75
118     constants_created = true; 76     constants_created = true;
119 } 77 }
120 78
121 #ifndef __NUITKA_NO_ASSERT__ 79 #ifndef __NUITKA_NO_ASSERT__
153 #ifndef __NUITKA_NO_ASSERT__ 111 #ifndef __NUITKA_NO_ASSERT__
154     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED(); 112     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED();
155 #endif 113 #endif
156 114
157     // Local variable declarations. 115     // Local variable declarations.
n 158     PyObject *exception_type = NULL, *exception_value = NULL; n
159     PyTracebackObject *exception_tb = NULL;
160     NUITKA_MAY_BE_UNUSED int exception_lineno = -1;
161     PyObject *tmp_called_name_1;
162     PyObject *tmp_called_name_2;
163     PyObject *tmp_called_name_3;
164     PyObject *tmp_frame_locals;
165     PyObject *tmp_return_value; 116     PyObject *tmp_return_value;
n 166     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused; n
167     static PyFrameObject *cache_frame_function = NULL;
168  
169     PyFrameObject *frame_function;
170  
171     tmp_return_value = NULL; 117     tmp_return_value = NULL;
172 118
173     // Actual function code. 119     // Actual function code.
n 174     MAKE_OR_REUSE_FRAME( cache_frame_function, codeobj_301f66b905051a6720475cf2f4197238, module___main__ ); n
175     frame_function = cache_frame_function;
176  
177     // Push the new frame as the currently active one.
178     pushFrameStack( frame_function );
179  
180     // Mark the frame object as in use, ref count 1 will be up for reuse.
181     Py_INCREF( frame_function );
182     assert( Py_REFCNT( frame_function ) == 2 ); // Frame stack
183  
184 #if PYTHON_VERSION >= 340
185     frame_function->f_executing += 1;
186 #endif
187  
188     // Framed code:
189     tmp_called_name_1 = GET_STRING_DICT_VALUE( moduledict___main__, (Nuitka_StringObject *)const_str_plain_python_func );
190  
191     if (unlikely( tmp_called_name_1 == NULL ))
192     {
193         tmp_called_name_1 = GET_STRING_DICT_VALUE( dict_builtin, (Nuitka_StringObject *)const_str_plain_python_func );
194     }
195  
196     if ( tmp_called_name_1 == NULL )
197     {
198  
199         exception_type = PyExc_NameError;
200         Py_INCREF( exception_type );
201         exception_value = PyUnicode_FromFormat( "name '%s' is not defined", "python_func" );
202         exception_tb = NULL;
203         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
204         CHAIN_EXCEPTION( exception_value );
205  
206         exception_lineno = 31;
207         goto frame_exception_exit_1;
208     }
209  
210     frame_function->f_lineno = 31;
211     tmp_unused = CALL_FUNCTION_WITH_ARGS6( tmp_called_name_1, &PyTuple_GET_ITEM( const_tuple_78e2f1ad354bdb7db1a0fda186168ee0_tuple, 0 ) );
212  
213     if ( tmp_unused == NULL )
214     {
215         assert( ERROR_OCCURRED() );
216  
217         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
218  
219  
220         exception_lineno = 31;
221         goto frame_exception_exit_1;
222     }
223     Py_DECREF( tmp_unused );
224     tmp_called_name_2 = GET_STRING_DICT_VALUE( moduledict___main__, (Nuitka_StringObject *)const_str_plain_python_func );
225  
226     if (unlikely( tmp_called_name_2 == NULL ))
227     {
228         tmp_called_name_2 = GET_STRING_DICT_VALUE( dict_builtin, (Nuitka_StringObject *)const_str_plain_python_func );
229     }
230  
231     if ( tmp_called_name_2 == NULL )
232     {
233  
234         exception_type = PyExc_NameError;
235         Py_INCREF( exception_type );
236         exception_value = PyUnicode_FromFormat( "name '%s' is not defined", "python_func" );
237         exception_tb = NULL;
238         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
239         CHAIN_EXCEPTION( exception_value );
240  
241         exception_lineno = 32;
242         goto frame_exception_exit_1;
243     }
244  
245     frame_function->f_lineno = 32;
246     tmp_unused = CALL_FUNCTION_WITH_ARGS6( tmp_called_name_2, &PyTuple_GET_ITEM( const_tuple_ca2f155a28955fc472d4376e2721d689_tuple, 0 ) );
247  
248     if ( tmp_unused == NULL )
249     {
250         assert( ERROR_OCCURRED() );
251  
252         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
253  
254  
255         exception_lineno = 32;
256         goto frame_exception_exit_1;
257     }
258     Py_DECREF( tmp_unused );
259     tmp_called_name_3 = GET_STRING_DICT_VALUE( moduledict___main__, (Nuitka_StringObject *)const_str_plain_python_func );
260  
261     if (unlikely( tmp_called_name_3 == NULL ))
262     {
263         tmp_called_name_3 = GET_STRING_DICT_VALUE( dict_builtin, (Nuitka_StringObject *)const_str_plain_python_func );
264     }
265  
266     if ( tmp_called_name_3 == NULL )
267     {
268  
269         exception_type = PyExc_NameError;
270         Py_INCREF( exception_type );
271         exception_value = PyUnicode_FromFormat( "name '%s' is not defined", "python_func" );
272         exception_tb = NULL;
273         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
274         CHAIN_EXCEPTION( exception_value );
275  
276         exception_lineno = 33;
277         goto frame_exception_exit_1;
278     }
279  
280     frame_function->f_lineno = 33;
281     tmp_unused = CALL_FUNCTION_WITH_ARGS6( tmp_called_name_3, &PyTuple_GET_ITEM( const_tuple_4cee4124c8df2995a8a82b981e580f5e_tuple, 0 ) );
282  
283     if ( tmp_unused == NULL )
284     {
285         assert( ERROR_OCCURRED() );
286  
287         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
288  
289  
290         exception_lineno = 33;
291         goto frame_exception_exit_1;
292     }
293     Py_DECREF( tmp_unused );
294  
295 #if 0
296     RESTORE_FRAME_EXCEPTION( frame_function );
297 #endif
298     // Put the previous frame back on top.
299     popFrameStack();
300 #if PYTHON_VERSION >= 340
301     frame_function->f_executing -= 1;
302 #endif
303     Py_DECREF( frame_function );
304     goto frame_no_exception_1;
305  
306     frame_exception_exit_1:;
307 #if 0
308     RESTORE_FRAME_EXCEPTION( frame_function );
309 #endif
310  
311     {
312         bool needs_detach = false;
313  
314         if ( exception_tb == NULL )
315         {
316             exception_tb = MAKE_TRACEBACK( frame_function, exception_lineno );
317             needs_detach = true;
318         }
319         else if ( exception_lineno != -1 )
320         {
321             PyTracebackObject *traceback_new = MAKE_TRACEBACK( frame_function, exception_lineno );
322             traceback_new->tb_next = exception_tb;
323             exception_tb = traceback_new;
324  
325             needs_detach = true;
326         }
327  
328         if (needs_detach)
329         {
330  
331             tmp_frame_locals = PyDict_New();
332  
333  
334             detachFrame( exception_tb, tmp_frame_locals );
335         }
336     }
337  
338     popFrameStack();
339  
340 #if PYTHON_VERSION >= 340
341     frame_function->f_executing -= 1;
342 #endif
343     Py_DECREF( frame_function );
344  
345     // Return the error.
346     goto function_exception_exit;
347  
348     frame_no_exception_1:;
349  
350     tmp_return_value = Py_None; 120     tmp_return_value = Py_None;
351     Py_INCREF( tmp_return_value ); 121     Py_INCREF( tmp_return_value );
352     goto function_return_exit; 122     goto function_return_exit;
353 123
354     // Return statement must have exited already. 124     // Return statement must have exited already.
355     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 125     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
356     return NULL; 126     return NULL;
357 127
t 358 function_exception_exit: t
359     assert( exception_type );
360     RESTORE_ERROR_OCCURRED( exception_type, exception_value, exception_tb );
361  
362     return NULL;
363     function_return_exit: 128     function_return_exit:
364 129
365     CHECK_OBJECT( tmp_return_value ); 130     CHECK_OBJECT( tmp_return_value );
366     assert( had_error || !ERROR_OCCURRED() ); 131     assert( had_error || !ERROR_OCCURRED() );
367     return tmp_return_value; 132     return tmp_return_value;