Construct FunctionCreationGeneratorLocal

Performance Diagrams

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