Construct FunctionCreationGeneratorLocal

Performance Diagrams

Construct FunctionCreationGeneratorLocal 00200000020000004000000400000060000006000000800000080000001000000010000000120000001200000014000000140000001600000016000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)1717965388.95192307692307257.0CPython 2.77850390242.31730769230768391.19388706064535Nuitka (master)7900386395.6826923076923390.47473512147457Nuitka (develop)7900387549.0480769230769390.47472073728505Nuitka (factory)Construct FunctionCreationGeneratorLocalTicks Construct FunctionCreationGeneratorLocal 002000000200000040000004000000600000060000008000000800000010000000100000001200000012000000140000001400000016000000160000001800000018000000200000002000000022000000220000002400000024000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)2503606788.95192307692307257.0CPython 3.59300675242.31730769230768412.3142291140955Nuitka (master)9450075395.6826923076923410.8395950007766Nuitka (develop)9450768549.0480769230769410.8327548304919Nuitka (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
36 static PyObject *const_str_plain_module_var; 36 static PyObject *const_str_plain_module_var;
37 extern PyObject *const_int_pos_1; 37 extern PyObject *const_int_pos_1;
38 extern PyObject *const_str_plain___file__; 38 extern PyObject *const_str_plain___file__;
39 extern PyObject *const_int_0; 39 extern PyObject *const_int_0;
40 static PyObject *const_str_plain_empty; 40 static PyObject *const_str_plain_empty;
n 41 static PyObject *const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd; n
42 extern PyObject *const_str_plain_print; 41 extern PyObject *const_str_plain_print;
43 static PyObject *const_int_pos_50000; 42 static PyObject *const_int_pos_50000;
44 static PyObject *const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple; 43 static PyObject *const_tuple_str_digest_5ed1392909ad16e6227b8230f4582352_tuple;
45 static PyObject *const_str_plain_calledRepeatedly; 44 static PyObject *const_str_plain_calledRepeatedly;
46 static PyObject *const_str_angle_module; 45 static PyObject *const_str_angle_module;
64     const_str_plain_itertools = UNSTREAM_STRING_ASCII(&constant_bin[ 38 ], 9, 1); 63     const_str_plain_itertools = UNSTREAM_STRING_ASCII(&constant_bin[ 38 ], 9, 1);
65     const_tuple_str_plain_empty_tuple = PyTuple_New(1); 64     const_tuple_str_plain_empty_tuple = PyTuple_New(1);
66     const_str_plain_empty = UNSTREAM_STRING_ASCII(&constant_bin[ 47 ], 5, 1); 65     const_str_plain_empty = UNSTREAM_STRING_ASCII(&constant_bin[ 47 ], 5, 1);
67     PyTuple_SET_ITEM(const_tuple_str_plain_empty_tuple, 0, const_str_plain_empty); Py_INCREF(const_str_plain_empty); 66     PyTuple_SET_ITEM(const_tuple_str_plain_empty_tuple, 0, const_str_plain_empty); Py_INCREF(const_str_plain_empty);
68     const_str_plain_module_var = UNSTREAM_STRING_ASCII(&constant_bin[ 52 ], 10, 1); 67     const_str_plain_module_var = UNSTREAM_STRING_ASCII(&constant_bin[ 52 ], 10, 1);
n 69     const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd = UNSTREAM_STRING_ASCII(&constant_bin[ 62 ], 31, 0); n
70     const_int_pos_50000 = PyLong_FromUnsignedLong(50000ul); 68     const_int_pos_50000 = PyLong_FromUnsignedLong(50000ul);
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_ASCII(&constant_bin[ 93 ], 3, 0); n 70     const_str_digest_5ed1392909ad16e6227b8230f4582352 = UNSTREAM_STRING_ASCII(&constant_bin[ 62 ], 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);
74     const_str_plain_calledRepeatedly = UNSTREAM_STRING_ASCII(&constant_bin[ 6 ], 16, 1); 72     const_str_plain_calledRepeatedly = UNSTREAM_STRING_ASCII(&constant_bin[ 6 ], 16, 1);
n 75     const_str_angle_module = UNSTREAM_STRING_ASCII(&constant_bin[ 96 ], 8, 0); n 73     const_str_angle_module = UNSTREAM_STRING_ASCII(&constant_bin[ 65 ], 8, 0);
76     const_str_plain_None = UNSTREAM_STRING_ASCII(&constant_bin[ 104 ], 4, 1); 74     const_str_plain_None = UNSTREAM_STRING_ASCII(&constant_bin[ 73 ], 4, 1);
77     const_str_plain_x = UNSTREAM_STRING_ASCII(&constant_bin[ 108 ], 1, 1); 75     const_str_plain_x = UNSTREAM_STRING_ASCII(&constant_bin[ 77 ], 1, 1);
78     const_str_plain_repeat = UNSTREAM_STRING_ASCII(&constant_bin[ 109 ], 6, 1); 76     const_str_plain_repeat = UNSTREAM_STRING_ASCII(&constant_bin[ 78 ], 6, 1);
79     const_tuple_none_int_pos_50000_tuple = PyTuple_New(2); 77     const_tuple_none_int_pos_50000_tuple = PyTuple_New(2);
80     PyTuple_SET_ITEM(const_tuple_none_int_pos_50000_tuple, 0, Py_None); Py_INCREF(Py_None); 78     PyTuple_SET_ITEM(const_tuple_none_int_pos_50000_tuple, 0, Py_None); Py_INCREF(Py_None);
81     PyTuple_SET_ITEM(const_tuple_none_int_pos_50000_tuple, 1, const_int_pos_50000); Py_INCREF(const_int_pos_50000); 79     PyTuple_SET_ITEM(const_tuple_none_int_pos_50000_tuple, 1, const_int_pos_50000); Py_INCREF(const_int_pos_50000);
n 82     const_str_digest_043d5745251b0dcc5d61147a7d0ddc84 = UNSTREAM_STRING_ASCII(&constant_bin[ 115 ], 55, 0); n 80     const_str_digest_043d5745251b0dcc5d61147a7d0ddc84 = UNSTREAM_STRING_ASCII(&constant_bin[ 84 ], 55, 0);
83 81
84     constants_created = true; 82     constants_created = true;
85 } 83 }
86 84
87 /* Function to verify module private constants for non-corruption. */ 85 /* Function to verify module private constants for non-corruption. */
96 #endif 94 #endif
97 95
98 // The module code objects. 96 // The module code objects.
99 static PyCodeObject *codeobj_4d1d55c1fcf0e7d3eafabc3631070616; 97 static PyCodeObject *codeobj_4d1d55c1fcf0e7d3eafabc3631070616;
100 static PyCodeObject *codeobj_2d1e24a3b8bba8d4c7ef224175ed65d0; 98 static PyCodeObject *codeobj_2d1e24a3b8bba8d4c7ef224175ed65d0;
n 101 static PyCodeObject *codeobj_0ed4057095d7866ba769790406c2effe; n
102 /* For use in "MainProgram.c". */ 99 /* For use in "MainProgram.c". */
103 PyCodeObject *codeobj_main = NULL; 100 PyCodeObject *codeobj_main = NULL;
104 101
105 static void createModuleCodeObjects(void) 102 static void createModuleCodeObjects(void)
106 { 103 {
107     module_filename_obj = const_str_digest_043d5745251b0dcc5d61147a7d0ddc84; 104     module_filename_obj = const_str_digest_043d5745251b0dcc5d61147a7d0ddc84;
108     codeobj_4d1d55c1fcf0e7d3eafabc3631070616 = MAKE_CODEOBJ(module_filename_obj, const_str_angle_module, 1, const_tuple_empty, 0, 0, CO_NOFREE); 105     codeobj_4d1d55c1fcf0e7d3eafabc3631070616 = MAKE_CODEOBJ(module_filename_obj, const_str_angle_module, 1, const_tuple_empty, 0, 0, CO_NOFREE);
109     codeobj_2d1e24a3b8bba8d4c7ef224175ed65d0 = MAKE_CODEOBJ(module_filename_obj, const_str_plain_calledRepeatedly, 23, const_tuple_str_plain_empty_tuple, 0, 0, CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE); 106     codeobj_2d1e24a3b8bba8d4c7ef224175ed65d0 = 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 110     codeobj_0ed4057095d7866ba769790406c2effe = MAKE_CODEOBJ(module_filename_obj, const_str_plain_empty, 26, const_tuple_empty, 0, 0, CO_GENERATOR | CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE); n
111 } 107 }
112 108
113 // The module function declarations. 109 // The module function declarations.
n 114 static PyObject *__main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_maker( void ); n
115  
116  
117 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly(); 110 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly();
n 118   n
119  
120 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty();
121 111
122 112
123 // The module function definitions. 113 // The module function definitions.
124 static PyObject *impl___main__$$$function_1_calledRepeatedly(struct Nuitka_FunctionObject const *self, PyObject **python_pars) { 114 static PyObject *impl___main__$$$function_1_calledRepeatedly(struct Nuitka_FunctionObject const *self, PyObject **python_pars) {
125     // Preserve error status for checks 115     // Preserve error status for checks
126 #ifndef __NUITKA_NO_ASSERT__ 116 #ifndef __NUITKA_NO_ASSERT__
127     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED(); 117     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED();
128 #endif 118 #endif
129 119
130     // Local variable declarations. 120     // Local variable declarations.
n 131     PyObject *var_empty = NULL; n
132     PyObject *tmp_return_value = NULL; 121     PyObject *tmp_return_value = NULL;
133 122
134     // Actual function body. 123     // Actual function body.
n 135     { n 124     tmp_return_value = const_int_pos_1;
136         PyObject *tmp_assign_source_1;
137         tmp_assign_source_1 = MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty();
138  
139  
140  
141         assert(var_empty == NULL);
142         var_empty = tmp_assign_source_1;
143     }
144     // Tried code:
145     CHECK_OBJECT(var_empty);
146     tmp_return_value = var_empty;
147     Py_INCREF(tmp_return_value); 125     Py_INCREF(tmp_return_value);
n 148     goto try_return_handler_1; n
149     // tried codes exits in all cases
150     NUITKA_CANNOT_GET_HERE(__main__$$$function_1_calledRepeatedly);
151     return NULL;
152     // Return handler code:
153     try_return_handler_1:;
154     CHECK_OBJECT((PyObject *)var_empty);
155     Py_DECREF(var_empty);
156     var_empty = NULL;
157  
158     goto function_return_exit; 126     goto function_return_exit;
n 159     // End of try: n
160 127
161     // Return statement must have exited already. 128     // Return statement must have exited already.
162     NUITKA_CANNOT_GET_HERE(__main__$$$function_1_calledRepeatedly); 129     NUITKA_CANNOT_GET_HERE(__main__$$$function_1_calledRepeatedly);
163     return NULL; 130     return NULL;
164 131
173    assert(had_error || !ERROR_OCCURRED()); 140    assert(had_error || !ERROR_OCCURRED());
174    return tmp_return_value; 141    return tmp_return_value;
175 } 142 }
176 143
177 144
n 178 static PyObject *impl___main__$$$function_1_calledRepeatedly$$$function_1_empty(struct Nuitka_FunctionObject const *self, PyObject **python_pars) { n
179     // Preserve error status for checks
180 #ifndef __NUITKA_NO_ASSERT__
181     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED();
182 #endif
183  
184     // Local variable declarations.
185     PyObject *tmp_return_value = NULL;
186  
187     // Actual function body.
188     tmp_return_value = __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_maker();
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  
199 function_return_exit:
200    // Function cleanup code if any.
201  
202  
203    // Actual function exit with return value, making sure we did not make
204    // the error status worse despite non-NULL return.
205    CHECK_OBJECT(tmp_return_value);
206    assert(had_error || !ERROR_OCCURRED());
207    return tmp_return_value;
208 }
209  
210  
211  
212 struct __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_locals {
213     char const *type_description_1;
214     PyObject *exception_type;
215     PyObject *exception_value;
216     PyTracebackObject *exception_tb;
217     int exception_lineno;
218 };
219  
220 static PyObject *__main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context( struct Nuitka_GeneratorObject *generator, PyObject *yield_return_value ) {
221     CHECK_OBJECT((PyObject *)generator);
222     assert(Nuitka_Generator_Check( (PyObject *)generator ));
223  
224     // Heap access if used.
225     struct __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_locals *generator_heap = (struct __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_locals *)generator->m_heap_storage;
226  
227     // Dispatch to yield based on return label index:
228     switch(generator->m_yield_return_index) {
229     case 1: goto yield_return_1;
230     }
231  
232     // Local variable initialization
233     static struct Nuitka_FrameObject *cache_m_frame = NULL;
234     generator_heap->type_description_1 = NULL;
235     generator_heap->exception_type = NULL;
236     generator_heap->exception_value = NULL;
237     generator_heap->exception_tb = NULL;
238     generator_heap->exception_lineno = 0;
239  
240     // Actual generator function body.
241     MAKE_OR_REUSE_FRAME(cache_m_frame, codeobj_0ed4057095d7866ba769790406c2effe, module___main__, 0);
242     generator->m_frame = cache_m_frame;
243  
244     // Mark the frame object as in use, ref count 1 will be up for reuse.
245     Py_INCREF(generator->m_frame);
246     assert(Py_REFCNT(generator->m_frame) == 2); // Frame stack
247  
248 #if PYTHON_VERSION >= 340
249     generator->m_frame->m_frame.f_gen = (PyObject *)generator;
250 #endif
251  
252     Py_CLEAR(generator->m_frame->m_frame.f_back);
253  
254     generator->m_frame->m_frame.f_back = PyThreadState_GET()->frame;
255     Py_INCREF(generator->m_frame->m_frame.f_back);
256  
257     PyThreadState_GET()->frame = &generator->m_frame->m_frame;
258     Py_INCREF(generator->m_frame);
259  
260     Nuitka_Frame_MarkAsExecuting(generator->m_frame);
261  
262 #if PYTHON_VERSION >= 300
263     // Accept currently existing exception as the one to publish again when we
264     // yield or yield from.
265     {
266         PyThreadState *thread_state = PyThreadState_GET();
267  
268         EXC_TYPE_F(generator) = EXC_TYPE(thread_state);
269         if (EXC_TYPE_F(generator) == Py_None) EXC_TYPE_F(generator) = NULL;
270         Py_XINCREF(EXC_TYPE_F(generator));
271         EXC_VALUE_F(generator) = EXC_VALUE(thread_state);
272         Py_XINCREF(EXC_VALUE_F(generator));
273         EXC_TRACEBACK_F(generator) = EXC_TRACEBACK(thread_state);
274         Py_XINCREF(EXC_TRACEBACK_F(generator));
275     }
276  
277 #endif
278  
279     // Framed code:
280     {
281         PyObject *tmp_expression_name_1;
282         NUITKA_MAY_BE_UNUSED PyObject *tmp_yield_result_1;
283         tmp_expression_name_1 = const_int_pos_1;
284         Py_INCREF(tmp_expression_name_1);
285         generator->m_yield_return_index = 1;
286         return tmp_expression_name_1;
287         yield_return_1:
288         if (yield_return_value == NULL) {
289             assert(ERROR_OCCURRED());
290  
291             FETCH_ERROR_OCCURRED(&generator_heap->exception_type, &generator_heap->exception_value, &generator_heap->exception_tb);
292  
293  
294             generator_heap->exception_lineno = 27;
295  
296             goto frame_exception_exit_1;
297         }
298         tmp_yield_result_1 = yield_return_value;
299     }
300  
301     Nuitka_Frame_MarkAsNotExecuting(generator->m_frame);
302  
303 #if PYTHON_VERSION >= 300
304     Py_CLEAR(EXC_TYPE_F(generator));
305     Py_CLEAR(EXC_VALUE_F(generator));
306     Py_CLEAR(EXC_TRACEBACK_F(generator));
307 #endif
308  
309     // Allow re-use of the frame again.
310     Py_DECREF(generator->m_frame);
311     goto frame_no_exception_1;
312  
313     frame_exception_exit_1:;
314  
315     // If it's not an exit exception, consider and create a traceback for it.
316     if (!EXCEPTION_MATCH_GENERATOR(generator_heap->exception_type)) {
317         if (generator_heap->exception_tb == NULL) {
318             generator_heap->exception_tb = MAKE_TRACEBACK(generator->m_frame, generator_heap->exception_lineno);
319         } else if (generator_heap->exception_tb->tb_frame != &generator->m_frame->m_frame) {
320             generator_heap->exception_tb = ADD_TRACEBACK(generator_heap->exception_tb, generator->m_frame, generator_heap->exception_lineno);
321         }
322  
323         Nuitka_Frame_AttachLocals(
324             (struct Nuitka_FrameObject *)generator->m_frame,
325             generator_heap->type_description_1
326         );
327  
328  
329         // Release cached frame.
330         if (generator->m_frame == cache_m_frame) {
331             Py_DECREF(generator->m_frame);
332         }
333         cache_m_frame = NULL;
334  
335         assertFrameObject(generator->m_frame);
336     }
337  
338 #if PYTHON_VERSION >= 300
339     Py_CLEAR(EXC_TYPE_F(generator));
340     Py_CLEAR(EXC_VALUE_F(generator));
341     Py_CLEAR(EXC_TRACEBACK_F(generator));
342 #endif
343  
344     Py_DECREF(generator->m_frame);
345  
346     // Return the error.
347     goto function_exception_exit;
348  
349     frame_no_exception_1:;
350  
351  
352     return NULL;
353  
354     function_exception_exit:
355     assert(generator_heap->exception_type);
356     RESTORE_ERROR_OCCURRED(generator_heap->exception_type, generator_heap->exception_value, generator_heap->exception_tb);
357  
358     return NULL;
359  
360 }
361  
362 static PyObject *__main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_maker( void )
363 {
364     return Nuitka_Generator_New(
365         __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context,
366         module___main__,
367         const_str_plain_empty,
368 #if PYTHON_VERSION >= 350
369         const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd,
370 #endif
371         codeobj_0ed4057095d7866ba769790406c2effe,
372         0,
373         sizeof(struct __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_locals)
374     );
375 }
376  
377  
378 145
379 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly() { 146 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly() {
380     struct Nuitka_FunctionObject *result = Nuitka_Function_New( 147     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
381         impl___main__$$$function_1_calledRepeatedly, 148         impl___main__$$$function_1_calledRepeatedly,
382         const_str_plain_calledRepeatedly, 149         const_str_plain_calledRepeatedly,
383 #if PYTHON_VERSION >= 300 150 #if PYTHON_VERSION >= 300
384         NULL, 151         NULL,
385 #endif 152 #endif
386         codeobj_2d1e24a3b8bba8d4c7ef224175ed65d0, 153         codeobj_2d1e24a3b8bba8d4c7ef224175ed65d0,
t 387         NULL, t
388 #if PYTHON_VERSION >= 300
389         NULL,
390         NULL,
391 #endif
392         module___main__,
393         NULL,
394         0
395     );
396  
397     return (PyObject *)result;
398 }
399  
400  
401  
402 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty() {
403     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
404         impl___main__$$$function_1_calledRepeatedly$$$function_1_empty,
405         const_str_plain_empty,
406 #if PYTHON_VERSION >= 300
407         const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd,
408 #endif
409         codeobj_0ed4057095d7866ba769790406c2effe,
410         NULL, 154         NULL,
411 #if PYTHON_VERSION >= 300 155 #if PYTHON_VERSION >= 300
412         NULL, 156         NULL,
413         NULL, 157         NULL,
414 #endif 158 #endif