Construct FunctionCreationGeneratorLocal

Performance Diagrams

Construct FunctionCreationGeneratorLocal 00200000020000004000000400000060000006000000800000080000001000000010000000120000001200000014000000140000001600000016000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)1652801188.95192307692307257.0CPython 2.78150546242.31730769230768382.25406024820063Nuitka (master)8149739395.6826923076923382.2661259538312Nuitka (develop)8150294549.0480769230769382.25782797783995Nuitka (factory)Construct FunctionCreationGeneratorLocalTicks Construct FunctionCreationGeneratorLocal 002000000200000040000004000000600000060000008000000800000010000000100000001200000012000000140000001400000016000000160000001800000018000000200000002000000022000000220000002400000024000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)2543340188.95192307692307257.0CPython 3.511401863242.31730769230768393.3328840533511Nuitka (master)11401191395.6826923076923393.33941332320626Nuitka (develop)11401243549.0480769230769393.3389080820865Nuitka (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
40 extern PyObject *const_dict_empty; 40 extern PyObject *const_dict_empty;
41 extern PyObject *const_str_plain___file__; 41 extern PyObject *const_str_plain___file__;
42 extern PyObject *const_int_0; 42 extern PyObject *const_int_0;
43 static PyObject *const_str_plain_empty; 43 static PyObject *const_str_plain_empty;
44 extern PyObject *const_str_plain_print; 44 extern PyObject *const_str_plain_print;
n 45 static PyObject *const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd; n
46 static PyObject *const_int_pos_50000; 45 static PyObject *const_int_pos_50000;
47 static PyObject *const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple; 46 static PyObject *const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple;
48 static PyObject *const_str_digest_f00a1b58a5cf36c89e231d6634ffc327; 47 static PyObject *const_str_digest_f00a1b58a5cf36c89e231d6634ffc327;
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;
68     const_str_plain___spec__ = UNSTREAM_STRING( &constant_bin[ 20 ], 8, 1 ); 67     const_str_plain___spec__ = UNSTREAM_STRING( &constant_bin[ 20 ], 8, 1 );
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 );
n 73     const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd = UNSTREAM_STRING( &constant_bin[ 43 ], 31, 0 ); n
74     const_int_pos_50000 = PyLong_FromUnsignedLong( 50000ul ); 72     const_int_pos_50000 = PyLong_FromUnsignedLong( 50000ul );
75     const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple = PyTuple_New( 1 ); 73     const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple = PyTuple_New( 1 );
n 76     const_str_digest_5ed1392909ad16e6227b8230f4582352 = UNSTREAM_STRING( &constant_bin[ 74 ], 3, 0 ); n 74     const_str_digest_5ed1392909ad16e6227b8230f4582352 = UNSTREAM_STRING( &constant_bin[ 43 ], 3, 0 );
77     PyTuple_SET_ITEM( const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple, 0, const_str_digest_5ed1392909ad16e6227b8230f4582352 ); Py_INCREF( const_str_digest_5ed1392909ad16e6227b8230f4582352 ); 75     PyTuple_SET_ITEM( const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple, 0, const_str_digest_5ed1392909ad16e6227b8230f4582352 ); Py_INCREF( const_str_digest_5ed1392909ad16e6227b8230f4582352 );
n 78     const_str_digest_f00a1b58a5cf36c89e231d6634ffc327 = UNSTREAM_STRING( &constant_bin[ 77 ], 88, 0 ); n 76     const_str_digest_f00a1b58a5cf36c89e231d6634ffc327 = UNSTREAM_STRING( &constant_bin[ 46 ], 88, 0 );
79     const_str_plain_calledRepeatedly = UNSTREAM_STRING( &constant_bin[ 43 ], 16, 1 ); 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[ 102 ], 1, 1 ); 79     const_str_plain_x = UNSTREAM_STRING( &constant_bin[ 71 ], 1, 1 );
82     const_str_plain_repeat = UNSTREAM_STRING( &constant_bin[ 173 ], 6, 1 ); 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_ddfb153c755ebe2dc0291ba184446e5e; 99 static PyCodeObject *codeobj_ddfb153c755ebe2dc0291ba184446e5e;
102 static PyCodeObject *codeobj_6e71c9354fac2371ebda0fa0b178ab50; 100 static PyCodeObject *codeobj_6e71c9354fac2371ebda0fa0b178ab50;
n 103 static PyCodeObject *codeobj_262258d5467f91c30de90a743e6cabcd; 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_f00a1b58a5cf36c89e231d6634ffc327; 106     module_filename_obj = const_str_digest_f00a1b58a5cf36c89e231d6634ffc327;
110     codeobj_ddfb153c755ebe2dc0291ba184446e5e = MAKE_CODEOBJ( module_filename_obj, const_str_angle_module, 1, const_tuple_empty, 0, 0, CO_NOFREE ); 107     codeobj_ddfb153c755ebe2dc0291ba184446e5e = MAKE_CODEOBJ( module_filename_obj, const_str_angle_module, 1, const_tuple_empty, 0, 0, CO_NOFREE );
111     codeobj_main = codeobj_ddfb153c755ebe2dc0291ba184446e5e; 108     codeobj_main = codeobj_ddfb153c755ebe2dc0291ba184446e5e;
112     codeobj_6e71c9354fac2371ebda0fa0b178ab50 = 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_6e71c9354fac2371ebda0fa0b178ab50 = 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_262258d5467f91c30de90a743e6cabcd = 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_262258d5467f91c30de90a743e6cabcd,
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     char const *type_description_1
230 };
231 #endif
232  
233 #if _NUITKA_EXPERIMENTAL_GENERATOR_GOTO
234 static PyObject *__main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context( struct Nuitka_GeneratorObject *generator, PyObject *yield_return_value )
235 #else
236 static void __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context( struct Nuitka_GeneratorObject *generator )
237 #endif
238 {
239     CHECK_OBJECT( (PyObject *)generator );
240     assert( Nuitka_Generator_Check( (PyObject *)generator ) );
241  
242     // Local variable initialization
243     PyObject *exception_type = NULL;
244     PyObject *exception_value = NULL;
245     PyTracebackObject *exception_tb = NULL;
246     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
247     PyObject *tmp_expression_name_1;
248     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused;
249     static struct Nuitka_FrameObject *cache_frame_generator = NULL;
250  
251     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
252  
253     // Dispatch to yield based on return label index:
254  
255  
256     // Actual function code.
257     MAKE_OR_REUSE_FRAME( cache_frame_generator, codeobj_262258d5467f91c30de90a743e6cabcd, module___main__, 0 );
258     generator->m_frame = cache_frame_generator;
259  
260     // Mark the frame object as in use, ref count 1 will be up for reuse.
261     Py_INCREF( generator->m_frame );
262     assert( Py_REFCNT( generator->m_frame ) == 2 ); // Frame stack
263  
264 #if PYTHON_VERSION >= 340
265     generator->m_frame->m_frame.f_gen = (PyObject *)generator;
266 #endif
267  
268     Py_CLEAR( generator->m_frame->m_frame.f_back );
269  
270     generator->m_frame->m_frame.f_back = PyThreadState_GET()->frame;
271     Py_INCREF( generator->m_frame->m_frame.f_back );
272  
273     PyThreadState_GET()->frame = &generator->m_frame->m_frame;
274     Py_INCREF( generator->m_frame );
275  
276     Nuitka_Frame_MarkAsExecuting( generator->m_frame );
277  
278 #if PYTHON_VERSION >= 300
279     // Accept currently existing exception as the one to publish again when we
280     // yield or yield from.
281  
282     PyThreadState *thread_state = PyThreadState_GET();
283  
284     generator->m_frame->m_frame.f_exc_type = thread_state->exc_type;
285     if ( generator->m_frame->m_frame.f_exc_type == Py_None ) generator->m_frame->m_frame.f_exc_type = NULL;
286     Py_XINCREF( generator->m_frame->m_frame.f_exc_type );
287     generator->m_frame->m_frame.f_exc_value = thread_state->exc_value;
288     Py_XINCREF( generator->m_frame->m_frame.f_exc_value );
289     generator->m_frame->m_frame.f_exc_traceback = thread_state->exc_traceback;
290     Py_XINCREF( generator->m_frame->m_frame.f_exc_traceback );
291 #endif
292  
293     // Framed code:
294     tmp_expression_name_1 = const_int_pos_1;
295     Py_INCREF( tmp_expression_name_1 );
296     tmp_unused = GENERATOR_YIELD( generator, tmp_expression_name_1 );
297     if ( tmp_unused == NULL )
298     {
299         assert( ERROR_OCCURRED() );
300  
301         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
302  
303  
304         exception_lineno = 27;
305  
306         goto frame_exception_exit_1;
307     }
308  
309     Nuitka_Frame_MarkAsNotExecuting( generator->m_frame );
310  
311 #if PYTHON_VERSION >= 300
312     Py_CLEAR( generator->m_frame->m_frame.f_exc_type );
313     Py_CLEAR( generator->m_frame->m_frame.f_exc_value );
314     Py_CLEAR( generator->m_frame->m_frame.f_exc_traceback );
315 #endif
316  
317     // Allow re-use of the frame again.
318     Py_DECREF( generator->m_frame );
319     goto frame_no_exception_1;
320  
321     frame_exception_exit_1:;
322  
323     // If it's not an exit exception, consider and create a traceback for it.
324     if ( !EXCEPTION_MATCH_GENERATOR( exception_type ) )
325     {
326         if ( exception_tb == NULL )
327         {
328             exception_tb = MAKE_TRACEBACK( generator->m_frame, exception_lineno );
329         }
330         else if ( exception_tb->tb_frame != &generator->m_frame->m_frame )
331         {
332             exception_tb = ADD_TRACEBACK( exception_tb, generator->m_frame, exception_lineno );
333         }
334  
335         Nuitka_Frame_AttachLocals(
336             (struct Nuitka_FrameObject *)generator->m_frame,
337             type_description_1
338         );
339  
340  
341         // Release cached frame.
342         if ( generator->m_frame == cache_frame_generator )
343         {
344             Py_DECREF( generator->m_frame );
345         }
346         cache_frame_generator = NULL;
347  
348         assertFrameObject( generator->m_frame );
349     }
350  
351 #if PYTHON_VERSION >= 300
352     Py_CLEAR( generator->m_frame->m_frame.f_exc_type );
353     Py_CLEAR( generator->m_frame->m_frame.f_exc_value );
354     Py_CLEAR( generator->m_frame->m_frame.f_exc_traceback );
355 #endif
356  
357     Py_DECREF( generator->m_frame );
358     // Return the error.
359     goto function_exception_exit;
360  
361     frame_no_exception_1:;
362  
363  
364 #if _NUITKA_EXPERIMENTAL_GENERATOR_GOTO
365     return NULL;
366 #else
367     generator->m_yielded = NULL;
368     return;
369 #endif
370  
371     function_exception_exit:
372     assert( exception_type );
373     RESTORE_ERROR_OCCURRED( exception_type, exception_value, exception_tb );
374  
375 #if _NUITKA_EXPERIMENTAL_GENERATOR_GOTO
376     return NULL;
377 #else
378     generator->m_yielded = NULL;
379     return;
380 #endif
381 142
382 } 143 }
383 144
384 145
385 146
390         const_str_plain_calledRepeatedly, 151         const_str_plain_calledRepeatedly,
391 #if PYTHON_VERSION >= 330 152 #if PYTHON_VERSION >= 330
392         NULL, 153         NULL,
393 #endif 154 #endif
394         codeobj_6e71c9354fac2371ebda0fa0b178ab50, 155         codeobj_6e71c9354fac2371ebda0fa0b178ab50,
t 395         NULL, t
396 #if PYTHON_VERSION >= 300
397         NULL,
398         const_dict_empty,
399 #endif
400         module___main__,
401         Py_None,
402         0
403     );
404  
405  
406     return (PyObject *)result;
407 }
408  
409  
410  
411 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty(  )
412 {
413     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
414         impl___main__$$$function_1_calledRepeatedly$$$function_1_empty,
415         const_str_plain_empty,
416 #if PYTHON_VERSION >= 330
417         const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd,
418 #endif
419         codeobj_262258d5467f91c30de90a743e6cabcd,
420         NULL, 156         NULL,
421 #if PYTHON_VERSION >= 300 157 #if PYTHON_VERSION >= 300
422         NULL, 158         NULL,
423         const_dict_empty, 159         const_dict_empty,
424 #endif 160 #endif