Construct FunctionCreationGeneratorLocal

Performance Diagrams

Construct FunctionCreationGeneratorLocal 00200000020000004000000400000060000006000000800000080000001000000010000000120000001200000014000000140000001600000016000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)1652801188.95192307692307257.0CPython 2.78150375242.31730769230768382.2566169218844Nuitka (master)8150351395.6826923076923382.25697575327865Nuitka (develop)8150954549.0480769230769382.24796011449894Nuitka (factory)Construct FunctionCreationGeneratorLocalTicks Construct FunctionCreationGeneratorLocal 002000000200000040000004000000600000060000008000000800000010000000100000001200000012000000140000001400000016000000160000001800000018000000200000002000000022000000220000002400000024000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)2543340188.95192307692307257.0CPython 3.511414481242.31730769230768393.2102853524115Nuitka (master)11399873395.6826923076923393.3522192423565Nuitka (develop)11399789549.0480769230769393.3530354010884Nuitka (factory)Construct FunctionCreationGeneratorLocalTicks

Source Code with Construct

module_var = None

def calledRepeatedly():
    # We measure making a local function that will remain unused.
# construct_begin
    def empty():
        yield 1
# construct_alternative



    return empty


import itertools
for x in itertools.repeat(None, 50000):
    calledRepeatedly()

print("OK.")

Source Code without Construct

module_var = None

def calledRepeatedly():
    # We measure making a local function that will remain unused.
# construct_begin


# construct_alternative
    empty = 1
# construct_end

    return empty


import itertools
for x in itertools.repeat(None, 50000):
    calledRepeatedly()

print("OK.")

Context Diff of Source Code


Construct
Baseline
21 module_var = None 21 module_var = None
22 22
23 def calledRepeatedly(): 23 def calledRepeatedly():
24     # We measure making a local function that will remain unused. 24     # We measure making a local function that will remain unused.
25 # construct_begin 25 # construct_begin
n 26     def empty(): n
27         yield 1
28 # construct_alternative
29 26
30 27
t t 28 # construct_alternative
29     empty = 1
30 # construct_end
31 31
32     return empty 32     return empty
33 33
34 34
35 import itertools 35 import itertools

Context Diff of Generated Code


Construct
Baseline
41 static PyObject *const_str_digest_18affa68186cdf68686aa7177dda829e; 41 static PyObject *const_str_digest_18affa68186cdf68686aa7177dda829e;
42 extern PyObject *const_str_plain___file__; 42 extern PyObject *const_str_plain___file__;
43 extern PyObject *const_int_0; 43 extern PyObject *const_int_0;
44 static PyObject *const_str_plain_empty; 44 static PyObject *const_str_plain_empty;
45 extern PyObject *const_str_plain_print; 45 extern PyObject *const_str_plain_print;
n 46 static PyObject *const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd; n
47 static PyObject *const_int_pos_50000; 46 static PyObject *const_int_pos_50000;
48 static PyObject *const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple; 47 static PyObject *const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple;
49 static PyObject *const_str_plain_calledRepeatedly; 48 static PyObject *const_str_plain_calledRepeatedly;
50 static PyObject *const_str_angle_module; 49 static PyObject *const_str_angle_module;
51 static PyObject *const_str_plain_x; 50 static PyObject *const_str_plain_x;
69     const_tuple_str_plain_empty_tuple = PyTuple_New( 1 ); 68     const_tuple_str_plain_empty_tuple = PyTuple_New( 1 );
70     const_str_plain_empty = UNSTREAM_STRING( &constant_bin[ 28 ], 5, 1 ); 69     const_str_plain_empty = UNSTREAM_STRING( &constant_bin[ 28 ], 5, 1 );
71     PyTuple_SET_ITEM( const_tuple_str_plain_empty_tuple, 0, const_str_plain_empty ); Py_INCREF( const_str_plain_empty ); 70     PyTuple_SET_ITEM( const_tuple_str_plain_empty_tuple, 0, const_str_plain_empty ); Py_INCREF( const_str_plain_empty );
72     const_str_plain_module_var = UNSTREAM_STRING( &constant_bin[ 33 ], 10, 1 ); 71     const_str_plain_module_var = UNSTREAM_STRING( &constant_bin[ 33 ], 10, 1 );
73     const_str_digest_18affa68186cdf68686aa7177dda829e = UNSTREAM_STRING( &constant_bin[ 43 ], 88, 0 ); 72     const_str_digest_18affa68186cdf68686aa7177dda829e = UNSTREAM_STRING( &constant_bin[ 43 ], 88, 0 );
n 74     const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd = UNSTREAM_STRING( &constant_bin[ 131 ], 31, 0 ); n
75     const_int_pos_50000 = PyLong_FromUnsignedLong( 50000ul ); 73     const_int_pos_50000 = PyLong_FromUnsignedLong( 50000ul );
76     const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple = PyTuple_New( 1 ); 74     const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple = PyTuple_New( 1 );
n 77     const_str_digest_5ed1392909ad16e6227b8230f4582352 = UNSTREAM_STRING( &constant_bin[ 162 ], 3, 0 ); n 75     const_str_digest_5ed1392909ad16e6227b8230f4582352 = UNSTREAM_STRING( &constant_bin[ 131 ], 3, 0 );
78     PyTuple_SET_ITEM( const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple, 0, const_str_digest_5ed1392909ad16e6227b8230f4582352 ); Py_INCREF( const_str_digest_5ed1392909ad16e6227b8230f4582352 ); 76     PyTuple_SET_ITEM( const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple, 0, const_str_digest_5ed1392909ad16e6227b8230f4582352 ); Py_INCREF( const_str_digest_5ed1392909ad16e6227b8230f4582352 );
n 79     const_str_plain_calledRepeatedly = UNSTREAM_STRING( &constant_bin[ 131 ], 16, 1 ); n 77     const_str_plain_calledRepeatedly = UNSTREAM_STRING( &constant_bin[ 134 ], 16, 1 );
80     const_str_angle_module = UNSTREAM_STRING( &constant_bin[ 165 ], 8, 0 ); 78     const_str_angle_module = UNSTREAM_STRING( &constant_bin[ 150 ], 8, 0 );
81     const_str_plain_x = UNSTREAM_STRING( &constant_bin[ 68 ], 1, 1 ); 79     const_str_plain_x = UNSTREAM_STRING( &constant_bin[ 68 ], 1, 1 );
n 82     const_str_plain_repeat = UNSTREAM_STRING( &constant_bin[ 173 ], 6, 1 ); n 80     const_str_plain_repeat = UNSTREAM_STRING( &constant_bin[ 158 ], 6, 1 );
83     const_tuple_none_int_pos_50000_tuple = PyTuple_New( 2 ); 81     const_tuple_none_int_pos_50000_tuple = PyTuple_New( 2 );
84     PyTuple_SET_ITEM( const_tuple_none_int_pos_50000_tuple, 0, Py_None ); Py_INCREF( Py_None ); 82     PyTuple_SET_ITEM( const_tuple_none_int_pos_50000_tuple, 0, Py_None ); Py_INCREF( Py_None );
85     PyTuple_SET_ITEM( const_tuple_none_int_pos_50000_tuple, 1, const_int_pos_50000 ); Py_INCREF( const_int_pos_50000 ); 83     PyTuple_SET_ITEM( const_tuple_none_int_pos_50000_tuple, 1, const_int_pos_50000 ); Py_INCREF( const_int_pos_50000 );
86 84
87     constants_created = true; 85     constants_created = true;
98 #endif 96 #endif
99 97
100 // The module code objects. 98 // The module code objects.
101 static PyCodeObject *codeobj_7cb9b2370daa005c6f00c46f97f6c3ed; 99 static PyCodeObject *codeobj_7cb9b2370daa005c6f00c46f97f6c3ed;
102 static PyCodeObject *codeobj_5bf26cc045a70382709aac081cdc1136; 100 static PyCodeObject *codeobj_5bf26cc045a70382709aac081cdc1136;
n 103 static PyCodeObject *codeobj_d32a57ab5a796b522d3bd55f163307a3; n
104 /* For use in "MainProgram.c". */ 101 /* For use in "MainProgram.c". */
105 PyCodeObject *codeobj_main = NULL; 102 PyCodeObject *codeobj_main = NULL;
106 103
107 static void createModuleCodeObjects(void) 104 static void createModuleCodeObjects(void)
108 { 105 {
109     module_filename_obj = const_str_digest_18affa68186cdf68686aa7177dda829e; 106     module_filename_obj = const_str_digest_18affa68186cdf68686aa7177dda829e;
110     codeobj_7cb9b2370daa005c6f00c46f97f6c3ed = MAKE_CODEOBJ( module_filename_obj, const_str_angle_module, 1, const_tuple_empty, 0, 0, CO_NOFREE ); 107     codeobj_7cb9b2370daa005c6f00c46f97f6c3ed = MAKE_CODEOBJ( module_filename_obj, const_str_angle_module, 1, const_tuple_empty, 0, 0, CO_NOFREE );
111     codeobj_main = codeobj_7cb9b2370daa005c6f00c46f97f6c3ed; 108     codeobj_main = codeobj_7cb9b2370daa005c6f00c46f97f6c3ed;
112     codeobj_5bf26cc045a70382709aac081cdc1136 = MAKE_CODEOBJ( module_filename_obj, const_str_plain_calledRepeatedly, 23, const_tuple_str_plain_empty_tuple, 0, 0, CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE ); 109     codeobj_5bf26cc045a70382709aac081cdc1136 = MAKE_CODEOBJ( module_filename_obj, const_str_plain_calledRepeatedly, 23, const_tuple_str_plain_empty_tuple, 0, 0, CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE );
n 113     codeobj_d32a57ab5a796b522d3bd55f163307a3 = MAKE_CODEOBJ( module_filename_obj, const_str_plain_empty, 26, const_tuple_empty, 0, 0, CO_GENERATOR | CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE ); n
114 } 110 }
115 111
116 // The module function declarations. 112 // The module function declarations.
n 117 #if _NUITKA_EXPERIMENTAL_GENERATOR_GOTO n
118 static PyObject *__main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context( struct Nuitka_GeneratorObject *generator, PyObject *yield_return_value );
119 #else
120 static void __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context( struct Nuitka_GeneratorObject *generator );
121 #endif
122  
123  
124 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly(  ); 113 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly(  );
n 125   n
126  
127 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty(  );
128 114
129 115
130 // The module function definitions. 116 // The module function definitions.
131 static PyObject *impl___main__$$$function_1_calledRepeatedly( struct Nuitka_FunctionObject const *self, PyObject **python_pars ) 117 static PyObject *impl___main__$$$function_1_calledRepeatedly( struct Nuitka_FunctionObject const *self, PyObject **python_pars )
132 { 118 {
134 #ifndef __NUITKA_NO_ASSERT__ 120 #ifndef __NUITKA_NO_ASSERT__
135     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED(); 121     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED();
136 #endif 122 #endif
137 123
138     // Local variable declarations. 124     // Local variable declarations.
n 139     PyObject *var_empty = NULL; n
140     PyObject *tmp_assign_source_1;
141     PyObject *tmp_return_value; 125     PyObject *tmp_return_value;
142     tmp_return_value = NULL; 126     tmp_return_value = NULL;
143 127
144     // Actual function code. 128     // Actual function code.
n 145     tmp_assign_source_1 = MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty(  ); n 129     tmp_return_value = const_int_pos_1;
146     assert( var_empty == NULL );
147     var_empty = tmp_assign_source_1;
148  
149     // Tried code:
150     tmp_return_value = var_empty;
151  
152     CHECK_OBJECT( tmp_return_value );
153     Py_INCREF( tmp_return_value ); 130     Py_INCREF( tmp_return_value );
n 154     goto try_return_handler_1; n
155     // tried codes exits in all cases
156     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
157     return NULL;
158     // Return handler code:
159     try_return_handler_1:;
160     CHECK_OBJECT( (PyObject *)var_empty );
161     Py_DECREF( var_empty );
162     var_empty = NULL;
163  
164     goto function_return_exit; 131     goto function_return_exit;
n 165     // End of try: n
166 132
167     // Return statement must have exited already. 133     // Return statement must have exited already.
168     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 134     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
169     return NULL; 135     return NULL;
170 136
171     function_return_exit: 137     function_return_exit:
172 138
173     CHECK_OBJECT( tmp_return_value ); 139     CHECK_OBJECT( tmp_return_value );
174     assert( had_error || !ERROR_OCCURRED() ); 140     assert( had_error || !ERROR_OCCURRED() );
175     return tmp_return_value; 141     return tmp_return_value;
n 176   n
177 }
178  
179  
180 static PyObject *impl___main__$$$function_1_calledRepeatedly$$$function_1_empty( struct Nuitka_FunctionObject const *self, PyObject **python_pars )
181 {
182     // Preserve error status for checks
183 #ifndef __NUITKA_NO_ASSERT__
184     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED();
185 #endif
186  
187     // Local variable declarations.
188     PyObject *tmp_return_value;
189     tmp_return_value = NULL;
190  
191     // Actual function code.
192     tmp_return_value = Nuitka_Generator_New(
193         __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context,
194         module___main__,
195         const_str_plain_empty,
196 #if PYTHON_VERSION >= 350
197         const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd,
198 #endif
199         codeobj_d32a57ab5a796b522d3bd55f163307a3,
200         0
201     );
202  
203     assert( Py_SIZE( tmp_return_value) >= 0 ); 
204  
205  
206     goto function_return_exit;
207  
208     // Return statement must have exited already.
209     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly$$$function_1_empty );
210     return NULL;
211  
212     function_return_exit:
213  
214     CHECK_OBJECT( tmp_return_value );
215     assert( had_error || !ERROR_OCCURRED() );
216     return tmp_return_value;
217  
218 }
219  
220  
221  
222 #if _NUITKA_EXPERIMENTAL_GENERATOR_GOTO
223 struct __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_locals {
224     PyObject *exception_type
225     PyObject *exception_value
226     PyTracebackObject *exception_tb
227     int exception_lineno
228     PyObject *tmp_expression_name_1;
229 };
230 #endif
231  
232 #if _NUITKA_EXPERIMENTAL_GENERATOR_GOTO
233 static PyObject *__main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context( struct Nuitka_GeneratorObject *generator, PyObject *yield_return_value )
234 #else
235 static void __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context( struct Nuitka_GeneratorObject *generator )
236 #endif
237 {
238     CHECK_OBJECT( (PyObject *)generator );
239     assert( Nuitka_Generator_Check( (PyObject *)generator ) );
240  
241     // Local variable initialization
242     PyObject *exception_type = NULL;
243     PyObject *exception_value = NULL;
244     PyTracebackObject *exception_tb = NULL;
245     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
246     PyObject *tmp_expression_name_1;
247     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused;
248     static struct Nuitka_FrameObject *cache_frame_generator = NULL;
249  
250  
251     // Dispatch to yield based on return label index:
252  
253  
254     // Actual function code.
255     MAKE_OR_REUSE_FRAME( cache_frame_generator, codeobj_d32a57ab5a796b522d3bd55f163307a3, module___main__, 0 );
256     generator->m_frame = cache_frame_generator;
257  
258     // Mark the frame object as in use, ref count 1 will be up for reuse.
259     Py_INCREF( generator->m_frame );
260     assert( Py_REFCNT( generator->m_frame ) == 2 ); // Frame stack
261  
262 #if PYTHON_VERSION >= 340
263     generator->m_frame->m_frame.f_gen = (PyObject *)generator;
264 #endif
265  
266     Py_CLEAR( generator->m_frame->m_frame.f_back );
267  
268     generator->m_frame->m_frame.f_back = PyThreadState_GET()->frame;
269     Py_INCREF( generator->m_frame->m_frame.f_back );
270  
271     PyThreadState_GET()->frame = &generator->m_frame->m_frame;
272     Py_INCREF( generator->m_frame );
273  
274     Nuitka_Frame_MarkAsExecuting( generator->m_frame );
275  
276 #if PYTHON_VERSION >= 300
277     // Accept currently existing exception as the one to publish again when we
278     // yield or yield from.
279  
280     PyThreadState *thread_state = PyThreadState_GET();
281  
282     generator->m_frame->m_frame.f_exc_type = thread_state->exc_type;
283     if ( generator->m_frame->m_frame.f_exc_type == Py_None ) generator->m_frame->m_frame.f_exc_type = NULL;
284     Py_XINCREF( generator->m_frame->m_frame.f_exc_type );
285     generator->m_frame->m_frame.f_exc_value = thread_state->exc_value;
286     Py_XINCREF( generator->m_frame->m_frame.f_exc_value );
287     generator->m_frame->m_frame.f_exc_traceback = thread_state->exc_traceback;
288     Py_XINCREF( generator->m_frame->m_frame.f_exc_traceback );
289 #endif
290  
291     // Framed code:
292     tmp_expression_name_1 = const_int_pos_1;
293     Py_INCREF( tmp_expression_name_1 );
294     tmp_unused = GENERATOR_YIELD( generator, tmp_expression_name_1 );
295     if ( tmp_unused == NULL )
296     {
297         assert( ERROR_OCCURRED() );
298  
299         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
300  
301  
302         exception_lineno = 27;
303  
304         goto frame_exception_exit_1;
305     }
306  
307     Nuitka_Frame_MarkAsNotExecuting( generator->m_frame );
308  
309 #if PYTHON_VERSION >= 300
310     Py_CLEAR( generator->m_frame->m_frame.f_exc_type );
311     Py_CLEAR( generator->m_frame->m_frame.f_exc_value );
312     Py_CLEAR( generator->m_frame->m_frame.f_exc_traceback );
313 #endif
314  
315     // Allow re-use of the frame again.
316     Py_DECREF( generator->m_frame );
317     goto frame_no_exception_1;
318  
319     frame_exception_exit_1:;
320  
321     // If it's not an exit exception, consider and create a traceback for it.
322     if ( !EXCEPTION_MATCH_GENERATOR( exception_type ) )
323     {
324         if ( exception_tb == NULL )
325         {
326             exception_tb = MAKE_TRACEBACK( generator->m_frame, exception_lineno );
327         }
328         else if ( exception_tb->tb_frame != &generator->m_frame->m_frame )
329         {
330             exception_tb = ADD_TRACEBACK( exception_tb, generator->m_frame, exception_lineno );
331         }
332  
333         Nuitka_Frame_AttachLocals( (struct Nuitka_FrameObject *)generator->m_frame, ""  );
334  
335         // Release cached frame.
336         if ( generator->m_frame == cache_frame_generator )
337         {
338             Py_DECREF( generator->m_frame );
339         }
340         cache_frame_generator = NULL;
341  
342         assertFrameObject( generator->m_frame );
343     }
344  
345 #if PYTHON_VERSION >= 300
346     Py_CLEAR( generator->m_frame->m_frame.f_exc_type );
347     Py_CLEAR( generator->m_frame->m_frame.f_exc_value );
348     Py_CLEAR( generator->m_frame->m_frame.f_exc_traceback );
349 #endif
350  
351     Py_DECREF( generator->m_frame );
352     // Return the error.
353     goto function_exception_exit;
354  
355     frame_no_exception_1:;
356  
357  
358 #if _NUITKA_EXPERIMENTAL_GENERATOR_GOTO
359     return NULL;
360 #else
361     generator->m_yielded = NULL;
362     return;
363 #endif
364  
365     function_exception_exit:
366     assert( exception_type );
367     RESTORE_ERROR_OCCURRED( exception_type, exception_value, exception_tb );
368  
369 #if _NUITKA_EXPERIMENTAL_GENERATOR_GOTO
370     return NULL;
371 #else
372     generator->m_yielded = NULL;
373     return;
374 #endif
375 142
376 } 143 }
377 144
378 145
379 146
384         const_str_plain_calledRepeatedly, 151         const_str_plain_calledRepeatedly,
385 #if PYTHON_VERSION >= 330 152 #if PYTHON_VERSION >= 330
386         NULL, 153         NULL,
387 #endif 154 #endif
388         codeobj_5bf26cc045a70382709aac081cdc1136, 155         codeobj_5bf26cc045a70382709aac081cdc1136,
t 389         NULL, t
390 #if PYTHON_VERSION >= 300
391         NULL,
392         const_dict_empty,
393 #endif
394         module___main__,
395         Py_None,
396         0
397     );
398  
399  
400     return (PyObject *)result;
401 }
402  
403  
404  
405 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty(  )
406 {
407     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
408         impl___main__$$$function_1_calledRepeatedly$$$function_1_empty,
409         const_str_plain_empty,
410 #if PYTHON_VERSION >= 330
411         const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd,
412 #endif
413         codeobj_d32a57ab5a796b522d3bd55f163307a3,
414         NULL, 156         NULL,
415 #if PYTHON_VERSION >= 300 157 #if PYTHON_VERSION >= 300
416         NULL, 158         NULL,
417         const_dict_empty, 159         const_dict_empty,
418 #endif 160 #endif