Construct FunctionCreationGeneratorLocal

Performance Diagrams

Construct FunctionCreationGeneratorLocal 00200000020000004000000400000060000006000000800000080000001000000010000000120000001200000014000000140000001600000016000000CPython 2.7Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)1652868173.61538461538461257.0CPython 2.711200020196.30769230769232336.66722284131447Nuitka (historic)8100785319.0000000000001383.00296185391096Nuitka (master)8100725441.69230769230774383.00385889603285Nuitka (develop)8100674564.3846153846155383.0046213818365Nuitka (factory)Construct FunctionCreationGeneratorLocalTicks Construct FunctionCreationGeneratorLocal 002000000200000040000004000000600000060000008000000800000010000000100000001200000012000000140000001400000016000000160000001800000018000000200000002000000022000000220000002400000024000000CPython 3.5Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)2543894973.61538461538461257.0CPython 3.50196.30769230769232504.11538461538464Nuitka (historic)11409969319.0000000000001393.27830255336175Nuitka (master)11413692441.69230769230774393.24213712149094Nuitka (develop)11418586564.3846153846155393.19459652960927Nuitka (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


for x in xrange(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


for x in xrange(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 for x in xrange(50000): 35 for x in xrange(50000):

Context Diff of Generated Code


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