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)8149432441.69230769230774382.2756550521531Nuitka (develop)8101267564.3846153846155382.99575561553144Nuitka (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)11406831441.69230769230774393.30878526225524Nuitka (develop)11406033564.3846153846155393.3165370792396Nuitka (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
40 extern PyObject *const_str_plain___file__; 40 extern PyObject *const_str_plain___file__;
41 extern PyObject *const_int_0; 41 extern PyObject *const_int_0;
42 static PyObject *const_xrange_0_50000; 42 static PyObject *const_xrange_0_50000;
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_plain_calledRepeatedly; 47 static PyObject *const_str_plain_calledRepeatedly;
49 static PyObject *const_str_angle_module; 48 static PyObject *const_str_angle_module;
50 static PyObject *const_str_plain_x; 49 static PyObject *const_str_plain_x;
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_digest_4ce014c35888ea6e2d627a9132973129 = UNSTREAM_STRING( &constant_bin[ 16 ], 88, 0 ); 66     const_str_digest_4ce014c35888ea6e2d627a9132973129 = UNSTREAM_STRING( &constant_bin[ 16 ], 88, 0 );
68     const_str_plain_module_var = UNSTREAM_STRING( &constant_bin[ 104 ], 10, 1 ); 67     const_str_plain_module_var = UNSTREAM_STRING( &constant_bin[ 104 ], 10, 1 );
69     const_int_pos_50000 = PyLong_FromUnsignedLong( 50000ul ); 68     const_int_pos_50000 = PyLong_FromUnsignedLong( 50000ul );
70     const_xrange_0_50000 = BUILTIN_XRANGE3( const_int_0, const_int_pos_50000, const_int_pos_1 ); 69     const_xrange_0_50000 = BUILTIN_XRANGE3( const_int_0, const_int_pos_50000, const_int_pos_1 );
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[ 41 ], 1, 1 ); 75     const_str_plain_x = UNSTREAM_STRING( &constant_bin[ 41 ], 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_114201cee898132417147effadacfba2; 91 static PyCodeObject *codeobj_114201cee898132417147effadacfba2;
94 static PyCodeObject *codeobj_532be3bdf595321c672d863d58d65596; 92 static PyCodeObject *codeobj_532be3bdf595321c672d863d58d65596;
n 95 static PyCodeObject *codeobj_fe7fa77f044a498230f5367f34a93da5; 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_4ce014c35888ea6e2d627a9132973129; 98     module_filename_obj = const_str_digest_4ce014c35888ea6e2d627a9132973129;
102     codeobj_114201cee898132417147effadacfba2 = MAKE_CODEOBJ( module_filename_obj, const_str_angle_module, 1, const_tuple_empty, 0, 0, CO_NOFREE ); 99     codeobj_114201cee898132417147effadacfba2 = MAKE_CODEOBJ( module_filename_obj, const_str_angle_module, 1, const_tuple_empty, 0, 0, CO_NOFREE );
103     codeobj_main = codeobj_114201cee898132417147effadacfba2; 100     codeobj_main = codeobj_114201cee898132417147effadacfba2;
104     codeobj_532be3bdf595321c672d863d58d65596 = 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_532be3bdf595321c672d863d58d65596 = 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_fe7fa77f044a498230f5367f34a93da5 = 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_fe7fa77f044a498230f5367f34a93da5,
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     PyObject *tmp_frame_locals;
219     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused;
220     static PyFrameObject *cache_frame_generator = NULL;
221  
222  
223     // Actual function code.
224     MAKE_OR_REUSE_FRAME( cache_frame_generator, codeobj_fe7fa77f044a498230f5367f34a93da5, module___main__ );
225     generator->m_frame = cache_frame_generator;
226     Py_INCREF( generator->m_frame );
227  
228 #if PYTHON_VERSION >= 340
229     generator->m_frame->f_gen = (PyObject *)generator;
230 #endif
231  
232     Py_CLEAR( generator->m_frame->f_back );
233  
234     generator->m_frame->f_back = PyThreadState_GET()->frame;
235     Py_INCREF( generator->m_frame->f_back );
236  
237     PyThreadState_GET()->frame = generator->m_frame;
238     Py_INCREF( generator->m_frame );
239  
240 #if PYTHON_VERSION >= 340
241     generator->m_frame->f_executing += 1;
242 #endif
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->f_exc_type = thread_state->exc_type;
251     if ( generator->m_frame->f_exc_type == Py_None ) generator->m_frame->f_exc_type = NULL;
252     Py_XINCREF( generator->m_frame->f_exc_type );
253     generator->m_frame->f_exc_value = thread_state->exc_value;
254     Py_XINCREF( generator->m_frame->f_exc_value );
255     generator->m_frame->f_exc_traceback = thread_state->exc_traceback;
256     Py_XINCREF( generator->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         goto frame_exception_exit_1;
271     }
272  
273 #if PYTHON_VERSION >= 340
274     generator->m_frame->f_executing -= 1;
275 #endif
276  
277 #if PYTHON_VERSION >= 300
278     Py_CLEAR( generator->m_frame->f_exc_type );
279     Py_CLEAR( generator->m_frame->f_exc_value );
280     Py_CLEAR( generator->m_frame->f_exc_traceback );
281 #endif
282  
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         int needs_detach = false;
292  
293         if ( exception_tb == NULL )
294         {
295             exception_tb = MAKE_TRACEBACK( generator->m_frame, exception_lineno );
296             needs_detach = true;
297         }
298         else if ( exception_tb->tb_frame != generator->m_frame )
299         {
300             PyTracebackObject *traceback_new = MAKE_TRACEBACK( generator->m_frame, exception_lineno );
301             traceback_new->tb_next = exception_tb;
302             exception_tb = traceback_new;
303  
304             needs_detach = true;
305         }
306  
307         if (needs_detach)
308         {
309  
310             tmp_frame_locals = PyDict_New();
311  
312  
313             detachFrame( exception_tb, tmp_frame_locals );
314         }
315     }
316  
317 #if PYTHON_VERSION >= 300
318     Py_CLEAR( generator->m_frame->f_exc_type );
319     Py_CLEAR( generator->m_frame->f_exc_value );
320     Py_CLEAR( generator->m_frame->f_exc_traceback );
321 #endif
322  
323     Py_DECREF( generator->m_frame );
324     // Return the error.
325     goto function_exception_exit;
326  
327     frame_no_exception_1:;
328  
329  
330     generator->m_yielded = NULL;
331     return;
332  
333     function_exception_exit:
334     assert( exception_type );
335     RESTORE_ERROR_OCCURRED( exception_type, exception_value, exception_tb );
336     generator->m_yielded = NULL;
337     return;
338 } 135 }
339 136
340 137
341 138
342 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly(  ) 139 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly(  )
346         const_str_plain_calledRepeatedly, 143         const_str_plain_calledRepeatedly,
347 #if PYTHON_VERSION >= 330 144 #if PYTHON_VERSION >= 330
348         NULL, 145         NULL,
349 #endif 146 #endif
350         codeobj_532be3bdf595321c672d863d58d65596, 147         codeobj_532be3bdf595321c672d863d58d65596,
t 351         NULL, t
352 #if PYTHON_VERSION >= 300
353         NULL,
354         const_dict_empty,
355 #endif
356         module___main__,
357         Py_None,
358         0
359     );
360  
361  
362     return (PyObject *)result;
363 }
364  
365  
366  
367 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty(  )
368 {
369     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
370         impl___main__$$$function_1_calledRepeatedly$$$function_1_empty,
371         const_str_plain_empty,
372 #if PYTHON_VERSION >= 330
373         const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd,
374 #endif
375         codeobj_fe7fa77f044a498230f5367f34a93da5,
376         NULL, 148         NULL,
377 #if PYTHON_VERSION >= 300 149 #if PYTHON_VERSION >= 300
378         NULL, 150         NULL,
379         const_dict_empty, 151         const_dict_empty,
380 #endif 152 #endif