Construct FunctionCreationGeneratorLocal

Performance Diagrams

Construct FunctionCreationGeneratorLocal 00100000010000002000000200000030000003000000400000040000005000000500000060000006000000700000070000008000000800000090000009000000100000001000000011000000110000001200000012000000130000001300000014000000140000001500000015000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)1502613788.95192307692307257.0CPython 2.77700338242.31730769230768377.477913751219Nuitka (master)8700335395.6826923076923361.0322602030561Nuitka (develop)8700335549.0480769230769361.0322602030561Nuitka (factory)Construct FunctionCreationGeneratorLocalTicks Construct FunctionCreationGeneratorLocal 00200000020000004000000400000060000006000000800000080000001000000010000000120000001200000014000000140000001600000016000000180000001800000020000000200000002200000022000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)2213253088.95192307692307257.0CPython 3.59550796242.31730769230768397.4782931069544Nuitka (master)10550796395.6826923076923386.31303614738476Nuitka (develop)10550796549.0480769230769386.31303614738476Nuitka (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
43 static PyObject *const_str_angle_module; 43 static PyObject *const_str_angle_module;
44 static PyObject *const_tuple_str_plain_empty_tuple; 44 static PyObject *const_tuple_str_plain_empty_tuple;
45 static PyObject *const_str_plain_x; 45 static PyObject *const_str_plain_x;
46 extern PyObject *const_str_plain___doc__; 46 extern PyObject *const_str_plain___doc__;
47 static PyObject *const_str_plain_empty; 47 static PyObject *const_str_plain_empty;
n 48 static PyObject *const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd; n
49 extern PyObject *const_str_plain_print; 48 extern PyObject *const_str_plain_print;
n n 49 static PyObject *const_str_digest_5ed1392909ad16e6227b8230f4582352;
50 static PyObject *const_str_digest_defbed7bfa83271cfb8f5748a024afc9; 50 static PyObject *const_str_digest_defbed7bfa83271cfb8f5748a024afc9;
51 extern PyObject *const_str_plain___cached__; 51 extern PyObject *const_str_plain___cached__;
n 52 static PyObject *const_str_digest_5ed1392909ad16e6227b8230f4582352; n
53 extern PyObject *const_tuple_empty; 52 extern PyObject *const_tuple_empty;
n n 53 static PyObject *const_int_pos_50000;
54 extern PyObject *const_int_pos_1; 54 extern PyObject *const_int_pos_1;
n 55 static PyObject *const_int_pos_50000; n
56 static PyObject *module_filename_obj; 55 static PyObject *module_filename_obj;
57 56
58 /* Indicator if this modules private constants were created yet. */ 57 /* Indicator if this modules private constants were created yet. */
59 static bool constants_created = false; 58 static bool constants_created = false;
60 59
71     const_str_angle_module = UNSTREAM_STRING_ASCII(&constant_bin[ 63 ], 8, 0); 70     const_str_angle_module = UNSTREAM_STRING_ASCII(&constant_bin[ 63 ], 8, 0);
72     const_tuple_str_plain_empty_tuple = PyTuple_New(1); 71     const_tuple_str_plain_empty_tuple = PyTuple_New(1);
73     const_str_plain_empty = UNSTREAM_STRING_ASCII(&constant_bin[ 71 ], 5, 1); 72     const_str_plain_empty = UNSTREAM_STRING_ASCII(&constant_bin[ 71 ], 5, 1);
74     PyTuple_SET_ITEM(const_tuple_str_plain_empty_tuple, 0, const_str_plain_empty); Py_INCREF(const_str_plain_empty); 73     PyTuple_SET_ITEM(const_tuple_str_plain_empty_tuple, 0, const_str_plain_empty); Py_INCREF(const_str_plain_empty);
75     const_str_plain_x = UNSTREAM_STRING_ASCII(&constant_bin[ 76 ], 1, 1); 74     const_str_plain_x = UNSTREAM_STRING_ASCII(&constant_bin[ 76 ], 1, 1);
n 76     const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd = UNSTREAM_STRING_ASCII(&constant_bin[ 77 ], 31, 0); n 75     const_str_digest_5ed1392909ad16e6227b8230f4582352 = UNSTREAM_STRING_ASCII(&constant_bin[ 77 ], 3, 0);
77     const_str_digest_defbed7bfa83271cfb8f5748a024afc9 = UNSTREAM_STRING_ASCII(&constant_bin[ 108 ], 55, 0); 76     const_str_digest_defbed7bfa83271cfb8f5748a024afc9 = UNSTREAM_STRING_ASCII(&constant_bin[ 80 ], 55, 0);
78     const_str_digest_5ed1392909ad16e6227b8230f4582352 = UNSTREAM_STRING_ASCII(&constant_bin[ 163 ], 3, 0);
79 77
80     constants_created = true; 78     constants_created = true;
81 } 79 }
82 80
83 /* Function to verify module private constants for non-corruption. */ 81 /* Function to verify module private constants for non-corruption. */
91 #endif 89 #endif
92 90
93 // The module code objects. 91 // The module code objects.
94 static PyCodeObject *codeobj_ff785d710af16c7800ca40716b2a8edf; 92 static PyCodeObject *codeobj_ff785d710af16c7800ca40716b2a8edf;
95 static PyCodeObject *codeobj_e6bc462a8dc3f63da70b0bf4b65206db; 93 static PyCodeObject *codeobj_e6bc462a8dc3f63da70b0bf4b65206db;
n 96 static PyCodeObject *codeobj_a11c28852850718ef34cd02e46734e67; n
97 /* For use in "MainProgram.c". */ 94 /* For use in "MainProgram.c". */
98 PyCodeObject *codeobj_main = NULL; 95 PyCodeObject *codeobj_main = NULL;
99 96
100 static void createModuleCodeObjects(void) { 97 static void createModuleCodeObjects(void) {
101     module_filename_obj = const_str_digest_defbed7bfa83271cfb8f5748a024afc9; 98     module_filename_obj = const_str_digest_defbed7bfa83271cfb8f5748a024afc9;
102     codeobj_ff785d710af16c7800ca40716b2a8edf = MAKE_CODEOBJECT(module_filename_obj, 1, CO_NOFREE, const_str_angle_module, const_tuple_empty, 0, 0, 0); 99     codeobj_ff785d710af16c7800ca40716b2a8edf = MAKE_CODEOBJECT(module_filename_obj, 1, CO_NOFREE, const_str_angle_module, const_tuple_empty, 0, 0, 0);
103     codeobj_e6bc462a8dc3f63da70b0bf4b65206db = MAKE_CODEOBJECT(module_filename_obj, 23, CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE, const_str_plain_calledRepeatedly, const_tuple_str_plain_empty_tuple, 0, 0, 0); 100     codeobj_e6bc462a8dc3f63da70b0bf4b65206db = MAKE_CODEOBJECT(module_filename_obj, 23, CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE, const_str_plain_calledRepeatedly, const_tuple_str_plain_empty_tuple, 0, 0, 0);
n 104     codeobj_a11c28852850718ef34cd02e46734e67 = MAKE_CODEOBJECT(module_filename_obj, 26, CO_GENERATOR | CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE, const_str_plain_empty, const_tuple_empty, 0, 0, 0); n
105 } 101 }
106 102
107 // The module function declarations. 103 // The module function declarations.
n 108 static PyObject *MAKE_GENERATOR___main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty(); 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     // Preserve error status for checks 109     // Preserve error status for checks
120 #ifndef __NUITKA_NO_ASSERT__ 110 #ifndef __NUITKA_NO_ASSERT__
121     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED(); 111     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED();
122 #endif 112 #endif
123 113
124     // Local variable declarations. 114     // Local variable declarations.
n 125     PyObject *var_empty = NULL; n
126     PyObject *tmp_return_value = NULL; 115     PyObject *tmp_return_value = NULL;
127 116
128     // Actual function body. 117     // Actual function body.
n 129     { n 118     tmp_return_value = const_int_pos_1;
130         PyObject *tmp_assign_source_1;
131  
132  
133         tmp_assign_source_1 = MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty();
134  
135         assert(var_empty == NULL);
136         var_empty = tmp_assign_source_1;
137     }
138     // Tried code:
139     CHECK_OBJECT(var_empty);
140     tmp_return_value = var_empty;
141     Py_INCREF(tmp_return_value); 119     Py_INCREF(tmp_return_value);
n 142     goto try_return_handler_1; n
143     NUITKA_CANNOT_GET_HERE("tried codes exits in all cases");
144     return NULL;
145     // Return handler code:
146     try_return_handler_1:;
147     CHECK_OBJECT(var_empty);
148     Py_DECREF(var_empty);
149     var_empty = NULL;
150  
151     goto function_return_exit; 120     goto function_return_exit;
n 152     // End of try: n
153 121
154     NUITKA_CANNOT_GET_HERE("Return statement must have exited already."); 122     NUITKA_CANNOT_GET_HERE("Return statement must have exited already.");
155     return NULL; 123     return NULL;
156 124
157 125
165    assert(had_error || !ERROR_OCCURRED()); 133    assert(had_error || !ERROR_OCCURRED());
166    return tmp_return_value; 134    return tmp_return_value;
167 } 135 }
168 136
169 137
n 170 static PyObject *impl___main__$$$function_1_calledRepeatedly$$$function_1_empty(struct Nuitka_FunctionObject const *self, PyObject **python_pars) { n
171     // Preserve error status for checks
172 #ifndef __NUITKA_NO_ASSERT__
173     NUITKA_MAY_BE_UNUSED bool had_error = ERROR_OCCURRED();
174 #endif
175  
176     // Local variable declarations.
177     PyObject *tmp_return_value = NULL;
178  
179     // Actual function body.
180  
181  
182     tmp_return_value = MAKE_GENERATOR___main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty();
183  
184     goto function_return_exit;
185  
186     NUITKA_CANNOT_GET_HERE("Return statement must have exited already.");
187     return NULL;
188  
189  
190 function_return_exit:
191    // Function cleanup code if any.
192  
193  
194    // Actual function exit with return value, making sure we did not make
195    // the error status worse despite non-NULL return.
196    CHECK_OBJECT(tmp_return_value);
197    assert(had_error || !ERROR_OCCURRED());
198    return tmp_return_value;
199 }
200  
201  
202  
203 struct __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_locals {
204     char const *type_description_1;
205     PyObject *exception_type;
206     PyObject *exception_value;
207     PyTracebackObject *exception_tb;
208     int exception_lineno;
209 };
210  
211 static PyObject *__main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context(struct Nuitka_GeneratorObject *generator, PyObject *yield_return_value) {
212     CHECK_OBJECT(generator);
213     assert(Nuitka_Generator_Check((PyObject *)generator));
214     CHECK_OBJECT_X(yield_return_value);
215  
216     // Heap access if used.
217     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;
218  
219     // Dispatch to yield based on return label index:
220     switch(generator->m_yield_return_index) {
221     case 1: goto yield_return_1;
222     }
223  
224     // Local variable initialization
225     NUITKA_MAY_BE_UNUSED nuitka_void tmp_unused;
226     static struct Nuitka_FrameObject *cache_m_frame = NULL;
227     generator_heap->type_description_1 = NULL;
228     generator_heap->exception_type = NULL;
229     generator_heap->exception_value = NULL;
230     generator_heap->exception_tb = NULL;
231     generator_heap->exception_lineno = 0;
232  
233     // Actual generator function body.
234     if (isFrameUnusable(cache_m_frame)) {
235         Py_XDECREF(cache_m_frame);
236  
237 #if _DEBUG_REFCOUNTS
238         if (cache_m_frame == NULL) {
239             count_active_frame_cache_instances += 1;
240         } else {
241             count_released_frame_cache_instances += 1;
242         }
243         count_allocated_frame_cache_instances += 1;
244 #endif
245         cache_m_frame = MAKE_FUNCTION_FRAME(codeobj_a11c28852850718ef34cd02e46734e67, module___main__, 0);
246 #if _DEBUG_REFCOUNTS
247     } else {
248         count_hit_frame_cache_instances += 1;
249 #endif
250     }
251     generator->m_frame = cache_m_frame;
252  
253     // Mark the frame object as in use, ref count 1 will be up for reuse.
254     Py_INCREF(generator->m_frame);
255     assert(Py_REFCNT(generator->m_frame) == 2); // Frame stack
256  
257 #if PYTHON_VERSION >= 340
258     generator->m_frame->m_frame.f_gen = (PyObject *)generator;
259 #endif
260  
261     assert(generator->m_frame->m_frame.f_back == NULL);
262     Py_CLEAR(generator->m_frame->m_frame.f_back);
263  
264     generator->m_frame->m_frame.f_back = PyThreadState_GET()->frame;
265     Py_INCREF(generator->m_frame->m_frame.f_back);
266  
267     PyThreadState_GET()->frame = &generator->m_frame->m_frame;
268     Py_INCREF(generator->m_frame);
269  
270     Nuitka_Frame_MarkAsExecuting(generator->m_frame);
271  
272 #if PYTHON_VERSION >= 300
273     // Accept currently existing exception as the one to publish again when we
274     // yield or yield from.
275     {
276         PyThreadState *thread_state = PyThreadState_GET();
277  
278         EXC_TYPE_F(generator) = EXC_TYPE(thread_state);
279         if (EXC_TYPE_F(generator) == Py_None) EXC_TYPE_F(generator) = NULL;
280         Py_XINCREF(EXC_TYPE_F(generator));
281         EXC_VALUE_F(generator) = EXC_VALUE(thread_state);
282         Py_XINCREF(EXC_VALUE_F(generator));
283         EXC_TRACEBACK_F(generator) = EXC_TRACEBACK(thread_state);
284         Py_XINCREF(EXC_TRACEBACK_F(generator));
285     }
286  
287 #endif
288  
289     // Framed code:
290     {
291         PyObject *tmp_expression_name_1;
292         NUITKA_MAY_BE_UNUSED PyObject *tmp_yield_result_1;
293         tmp_expression_name_1 = const_int_pos_1;
294         Py_INCREF(tmp_expression_name_1);
295         generator->m_yield_return_index = 1;
296         return tmp_expression_name_1;
297         yield_return_1:
298         if (yield_return_value == NULL) {
299             assert(ERROR_OCCURRED());
300  
301             FETCH_ERROR_OCCURRED(&generator_heap->exception_type, &generator_heap->exception_value, &generator_heap->exception_tb);
302  
303  
304             generator_heap->exception_lineno = 27;
305  
306             goto frame_exception_exit_1;
307         }
308         tmp_yield_result_1 = yield_return_value;
309     }
310  
311     Nuitka_Frame_MarkAsNotExecuting(generator->m_frame);
312  
313 #if PYTHON_VERSION >= 300
314     Py_CLEAR(EXC_TYPE_F(generator));
315     Py_CLEAR(EXC_VALUE_F(generator));
316     Py_CLEAR(EXC_TRACEBACK_F(generator));
317 #endif
318  
319     // Allow re-use of the frame again.
320     Py_DECREF(generator->m_frame);
321     goto frame_no_exception_1;
322  
323     frame_exception_exit_1:;
324  
325     // If it's not an exit exception, consider and create a traceback for it.
326     if (!EXCEPTION_MATCH_GENERATOR(generator_heap->exception_type)) {
327         if (generator_heap->exception_tb == NULL) {
328             generator_heap->exception_tb = MAKE_TRACEBACK(generator->m_frame, generator_heap->exception_lineno);
329         } else if (generator_heap->exception_tb->tb_frame != &generator->m_frame->m_frame) {
330             generator_heap->exception_tb = ADD_TRACEBACK(generator_heap->exception_tb, generator->m_frame, generator_heap->exception_lineno);
331         }
332  
333         Nuitka_Frame_AttachLocals(
334             generator->m_frame,
335             generator_heap->type_description_1
336         );
337  
338  
339         // Release cached frame.
340         if (generator->m_frame == cache_m_frame) {
341 #if _DEBUG_REFCOUNTS
342             count_active_frame_cache_instances -= 1;
343             count_released_frame_cache_instances += 1;
344 #endif
345  
346             Py_DECREF(generator->m_frame);
347         }
348         cache_m_frame = NULL;
349  
350         assertFrameObject(generator->m_frame);
351     }
352  
353 #if PYTHON_VERSION >= 300
354     Py_CLEAR(EXC_TYPE_F(generator));
355     Py_CLEAR(EXC_VALUE_F(generator));
356     Py_CLEAR(EXC_TRACEBACK_F(generator));
357 #endif
358  
359     Py_DECREF(generator->m_frame);
360  
361     // Return the error.
362     goto function_exception_exit;
363  
364     frame_no_exception_1:;
365  
366  
367     return NULL;
368  
369     function_exception_exit:
370     assert(generator_heap->exception_type);
371     RESTORE_ERROR_OCCURRED(generator_heap->exception_type, generator_heap->exception_value, generator_heap->exception_tb);
372  
373     return NULL;
374  
375 }
376  
377 static PyObject *MAKE_GENERATOR___main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty() {
378     return Nuitka_Generator_New(
379         __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_context,
380         module___main__,
381         const_str_plain_empty,
382 #if PYTHON_VERSION >= 350
383         const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd,
384 #endif
385         codeobj_a11c28852850718ef34cd02e46734e67,
386         NULL,
387         0,
388         sizeof(struct __main__$$$function_1_calledRepeatedly$$$function_1_empty$$$genobj_1_empty_locals)
389     );
390 }
391  
392  
393 138
394 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly() { 139 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly() {
395     struct Nuitka_FunctionObject *result = Nuitka_Function_New( 140     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
396         impl___main__$$$function_1_calledRepeatedly, 141         impl___main__$$$function_1_calledRepeatedly,
397         const_str_plain_calledRepeatedly, 142         const_str_plain_calledRepeatedly,
412 157
413     return (PyObject *)result; 158     return (PyObject *)result;
414 } 159 }
415 160
416 161
n 417   n
418 static PyObject *MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_empty() {
419     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
420         impl___main__$$$function_1_calledRepeatedly$$$function_1_empty,
421         const_str_plain_empty,
422 #if PYTHON_VERSION >= 300
423         const_str_digest_30e4724e0d508bc0c811d26a46d4b6cd,
424 #endif
425         codeobj_a11c28852850718ef34cd02e46734e67,
426         NULL,
427 #if PYTHON_VERSION >= 300
428         NULL,
429         NULL,
430 #endif
431         module___main__,
432         NULL,
433         NULL,
434         0
435     );
436  
437     return (PyObject *)result;
438 }
439  
440  
441 extern PyObject *const_str_plain___compiled__; 162 extern PyObject *const_str_plain___compiled__;
442 163
443 extern PyObject *const_str_plain___package__; 164 extern PyObject *const_str_plain___package__;
444 extern PyObject *const_str_empty; 165 extern PyObject *const_str_empty;
445 166
465 #ifdef _NUITKA_PLUGIN_DILL_ENABLED 186 #ifdef _NUITKA_PLUGIN_DILL_ENABLED
466 // Provide a way to create find a function via its C code and create it back 187 // Provide a way to create find a function via its C code and create it back
467 // in another process, useful for multiprocessing extensions like dill 188 // in another process, useful for multiprocessing extensions like dill
468 189
469 function_impl_code functable___main__[] = { 190 function_impl_code functable___main__[] = {
t 470     impl___main__$$$function_1_calledRepeatedly$$$function_1_empty, t
471     impl___main__$$$function_1_calledRepeatedly, 191     impl___main__$$$function_1_calledRepeatedly,
472     NULL 192     NULL
473 }; 193 };
474 194
475 static char const *_reduce_compiled_function_argnames[] = { 195 static char const *_reduce_compiled_function_argnames[] = {