Construct FunctionCreationLocal

Performance Diagrams

Construct FunctionCreationLocal 00200000020000004000000400000060000006000000800000080000001000000010000000120000001200000014000000140000001600000016000000180000001800000020000000200000002200000022000000240000002400000026000000260000002800000028000000CPython 3.10Nuitka (main)Nuitka (develop)Nuitka (factory)2913130988.95192307692307257.0CPython 3.1010153248242.31730769230768417.98730212463954Nuitka (main)10153515395.6826923076923417.9850372141375Nuitka (develop)10153515549.0480769230769417.9850372141375Nuitka (factory)Construct FunctionCreationLocalTicks Construct FunctionCreationLocal 00200000020000004000000400000060000006000000800000080000001000000010000000120000001200000014000000140000001600000016000000180000001800000020000000200000002200000022000000CPython 3.8Nuitka (main)Nuitka (develop)Nuitka (factory)2207079188.95192307692307257.0CPython 3.810217450242.31730769230768389.7158106926167Nuitka (main)10223929395.6826923076923389.64326863569977Nuitka (develop)10223929549.0480769230769389.64326863569977Nuitka (factory)Construct FunctionCreationLocalTicks Construct FunctionCreationLocal 0010000001000000200000020000003000000300000040000004000000500000050000006000000600000070000007000000800000080000009000000900000010000000100000001100000011000000120000001200000013000000130000001400000014000000CPython 2.7Nuitka (main)Nuitka (develop)Nuitka (factory)1446889788.95192307692307257.0CPython 2.78151040242.31730769230768364.90315685432Nuitka (main)8151040395.6826923076923364.90315685432Nuitka (develop)8151040549.0480769230769364.90315685432Nuitka (factory)Construct FunctionCreationLocalTicks

Source Code with Construct

for x in itertools.repeat(None, 50000):
    calledRepeatedly()

print("OK.")

#     Python test originally created or extracted from other peoples work. The
#     parts from me are licensed as below. It is at least Free Software where
#     it's copied from other people. In these cases, that will normally be
#     indicated.
#
#     Licensed under the Apache License, Version 2.0 (the "License");
#     you may not use this file except in compliance with the License.
#     You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS,
#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#     See the License for the specific language governing permissions and
#     limitations under the License.

Source Code without Construct

for x in itertools.repeat(None, 50000):
    calledRepeatedly()

print("OK.")

#     Python test originally created or extracted from other peoples work. The
#     parts from me are licensed as below. It is at least Free Software where
#     it's copied from other people. In these cases, that will normally be
#     indicated.
#
#     Licensed under the Apache License, Version 2.0 (the "License");
#     you may not use this file except in compliance with the License.
#     You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS,
#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#     See the License for the specific language governing permissions and
#     limitations under the License.

Context Diff of Source Code


Construct
Baseline
5 5
6 6
7 def calledRepeatedly(): 7 def calledRepeatedly():
8     # We measure making a local function that will remain unused. 8     # We measure making a local function that will remain unused.
9     # construct_begin 9     # construct_begin
n 10     def empty(): n 10  
11         pass 11  
12 12
13     # construct_alternative 13     # construct_alternative
t 14   t 14     empty = 1
15   15     # construct_end
16 16
17     return empty 17     return empty
18 18
19 19
20 for x in itertools.repeat(None, 50000): 20 for x in itertools.repeat(None, 50000):

Context Diff of Generated Code


Construct
Baseline
31 31
32 PyObject *module___main__; 32 PyObject *module___main__;
33 PyDictObject *moduledict___main__; 33 PyDictObject *moduledict___main__;
34 34
35 /* The declarations of module constants used, if any. */ 35 /* The declarations of module constants used, if any. */
n 36 static PyObject *mod_consts[13]; n 36 static PyObject *mod_consts[12];
37 #ifndef __NUITKA_NO_ASSERT__ 37 #ifndef __NUITKA_NO_ASSERT__
n 38 static Py_hash_t mod_consts_hash[13]; n 38 static Py_hash_t mod_consts_hash[12];
39 #endif 39 #endif
40 40
41 static PyObject *module_filename_obj = NULL; 41 static PyObject *module_filename_obj = NULL;
42 42
43 /* Indicator if this modules private constants were created yet. */ 43 /* Indicator if this modules private constants were created yet. */
48     if (constants_created == false) { 48     if (constants_created == false) {
49         loadConstantsBlob(tstate, &mod_consts[0], UNTRANSLATE("__main__")); 49         loadConstantsBlob(tstate, &mod_consts[0], UNTRANSLATE("__main__"));
50         constants_created = true; 50         constants_created = true;
51 51
52 #ifndef __NUITKA_NO_ASSERT__ 52 #ifndef __NUITKA_NO_ASSERT__
n 53         for (int i = 0; i < 13; i++) { n 53         for (int i = 0; i < 12; i++) {
54             mod_consts_hash[i] = DEEP_HASH(tstate, mod_consts[i]); 54             mod_consts_hash[i] = DEEP_HASH(tstate, mod_consts[i]);
55         } 55         }
56 #endif 56 #endif
57     } 57     }
58 } 58 }
68 #ifndef __NUITKA_NO_ASSERT__ 68 #ifndef __NUITKA_NO_ASSERT__
69 void checkModuleConstants___main__(PyThreadState *tstate) { 69 void checkModuleConstants___main__(PyThreadState *tstate) {
70     // The module may not have been used at all, then ignore this. 70     // The module may not have been used at all, then ignore this.
71     if (constants_created == false) return; 71     if (constants_created == false) return;
72 72
n 73     for (int i = 0; i < 13; i++) { n 73     for (int i = 0; i < 12; i++) {
74         assert(mod_consts_hash[i] == DEEP_HASH(tstate, mod_consts[i])); 74         assert(mod_consts_hash[i] == DEEP_HASH(tstate, mod_consts[i]));
75         CHECK_OBJECT_DEEP(mod_consts[i]); 75         CHECK_OBJECT_DEEP(mod_consts[i]);
76     } 76     }
77 } 77 }
78 #endif 78 #endif
79 79
80 // The module code objects. 80 // The module code objects.
81 static PyCodeObject *codeobj_82f8b6bedeb3c2e417b651aedd191d64; 81 static PyCodeObject *codeobj_82f8b6bedeb3c2e417b651aedd191d64;
82 static PyCodeObject *codeobj_819405df0bfad9d8f9b408c2dbae75a9; 82 static PyCodeObject *codeobj_819405df0bfad9d8f9b408c2dbae75a9;
n 83 static PyCodeObject *codeobj_d5ef21224ea59cc035a7ace3738b3bbb; n
84 /* For use in "MainProgram.c". */ 83 /* For use in "MainProgram.c". */
85 PyCodeObject *codeobj_main = NULL; 84 PyCodeObject *codeobj_main = NULL;
86 85
87 static void createModuleCodeObjects(void) { 86 static void createModuleCodeObjects(void) {
n 88     module_filename_obj = mod_consts[2]; CHECK_OBJECT(module_filename_obj); n 87     module_filename_obj = mod_consts[1]; CHECK_OBJECT(module_filename_obj);
89     codeobj_82f8b6bedeb3c2e417b651aedd191d64 = MAKE_CODE_OBJECT(module_filename_obj, 1, CO_NOFREE, mod_consts[10], mod_consts[10], NULL, NULL, 0, 0, 0); 88     codeobj_82f8b6bedeb3c2e417b651aedd191d64 = MAKE_CODE_OBJECT(module_filename_obj, 1, CO_NOFREE, mod_consts[10], mod_consts[10], NULL, NULL, 0, 0, 0);
90     codeobj_main = codeobj_82f8b6bedeb3c2e417b651aedd191d64; 89     codeobj_main = codeobj_82f8b6bedeb3c2e417b651aedd191d64;
91     codeobj_819405df0bfad9d8f9b408c2dbae75a9 = MAKE_CODE_OBJECT(module_filename_obj, 7, CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE, mod_consts[5], mod_consts[5], mod_consts[11], NULL, 0, 0, 0); 90     codeobj_819405df0bfad9d8f9b408c2dbae75a9 = MAKE_CODE_OBJECT(module_filename_obj, 7, CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE, mod_consts[5], mod_consts[5], mod_consts[11], NULL, 0, 0, 0);
n 92     codeobj_d5ef21224ea59cc035a7ace3738b3bbb = MAKE_CODE_OBJECT(module_filename_obj, 10, CO_NOFREE, mod_consts[0], mod_consts[12], NULL, NULL, 0, 0, 0); n
93 } 91 }
94 92
95 // The module function declarations. 93 // The module function declarations.
96 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly(); 94 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly();
97 95
98 96
n 99 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly$$$function__1_empty(); n
100  
101  
102 // The module function definitions. 97 // The module function definitions.
n 103 static PyObject *impl___main__$$$function__1_calledRepeatedly(PyThreadState *tstate, struct Nuitka_FunctionObject const *self, PyObject **python_pars) { n
104     // Preserve error status for checks
105 #ifndef __NUITKA_NO_ASSERT__
106     NUITKA_MAY_BE_UNUSED bool had_error = HAS_ERROR_OCCURRED(tstate);
107 #endif
108  
109     // Local variable declarations.
110     PyObject *var_empty = NULL;
111     PyObject *tmp_return_value = NULL;
112  
113     // Actual function body.
114     {
115         PyObject *tmp_assign_source_1;
116  
117  
118         tmp_assign_source_1 = MAKE_FUNCTION___main__$$$function__1_calledRepeatedly$$$function__1_empty();
119  
120         assert(var_empty == NULL);
121         var_empty = tmp_assign_source_1;
122     }
123     // Tried code:
124     CHECK_OBJECT(var_empty);
125     tmp_return_value = var_empty;
126     Py_INCREF(tmp_return_value);
127     goto try_return_handler_1;
128     NUITKA_CANNOT_GET_HERE("tried codes exits in all cases");
129     return NULL;
130     // Return handler code:
131     try_return_handler_1:;
132     CHECK_OBJECT(var_empty);
133     Py_DECREF(var_empty);
134     var_empty = NULL;
135     goto function_return_exit;
136     // End of try:
137  
138     NUITKA_CANNOT_GET_HERE("Return statement must have exited already.");
139     return NULL;
140  
141  
142 function_return_exit:
143    // Function cleanup code if any.
144  
145  
146    // Actual function exit with return value, making sure we did not make
147    // the error status worse despite non-NULL return.
148    CHECK_OBJECT(tmp_return_value);
149    assert(had_error || !HAS_ERROR_OCCURRED(tstate));
150    return tmp_return_value;
151 }
152  
153  
154 98
155 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly() { 99 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly() {
156     struct Nuitka_FunctionObject *result = Nuitka_Function_New( 100     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
n 157         impl___main__$$$function__1_calledRepeatedly, n 101         NULL,
158         mod_consts[5], 102         mod_consts[5],
159 #if PYTHON_VERSION >= 0x300 103 #if PYTHON_VERSION >= 0x300
160         NULL, 104         NULL,
161 #endif 105 #endif
162         codeobj_819405df0bfad9d8f9b408c2dbae75a9, 106         codeobj_819405df0bfad9d8f9b408c2dbae75a9,
168         module___main__, 112         module___main__,
169         NULL, 113         NULL,
170         NULL, 114         NULL,
171         0 115         0
172     ); 116     );
n 173   n 117     Nuitka_Function_EnableConstReturnGeneric(result, mod_consts[4]);
174  
175     return (PyObject *)result;
176 }
177  
178  
179  
180 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly$$$function__1_empty() {
181     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
182         NULL,
183         mod_consts[0],
184 #if PYTHON_VERSION >= 0x300
185         NULL,
186 #endif
187         codeobj_d5ef21224ea59cc035a7ace3738b3bbb,
188         NULL,
189 #if PYTHON_VERSION >= 0x300
190         NULL,
191         NULL,
192 #endif
193         module___main__,
194         NULL,
195         NULL,
196         0
197     );
198  
199 118
200     return (PyObject *)result; 119     return (PyObject *)result;
201 } 120 }
202 121
203 122
213 // Provide a way to create find a function via its C code and create it back 132 // Provide a way to create find a function via its C code and create it back
214 // in another process, useful for multiprocessing extensions like dill 133 // in another process, useful for multiprocessing extensions like dill
215 extern void registerDillPluginTables(PyThreadState *tstate, char const *module_name, PyMethodDef *reduce_compiled_function, PyMethodDef *create_compiled_function); 134 extern void registerDillPluginTables(PyThreadState *tstate, char const *module_name, PyMethodDef *reduce_compiled_function, PyMethodDef *create_compiled_function);
216 135
217 static function_impl_code const function_table___main__[] = { 136 static function_impl_code const function_table___main__[] = {
n 218     impl___main__$$$function__1_calledRepeatedly, n 137  
219     NULL 138     NULL
220 }; 139 };
221 140
222 static PyObject *_reduce_compiled_function(PyObject *self, PyObject *args, PyObject *kwds) { 141 static PyObject *_reduce_compiled_function(PyObject *self, PyObject *args, PyObject *kwds) {
223     PyObject *func; 142     PyObject *func;
568 487
569     // Module code. 488     // Module code.
570     { 489     {
571         PyObject *tmp_assign_source_1; 490         PyObject *tmp_assign_source_1;
572         tmp_assign_source_1 = Py_None; 491         tmp_assign_source_1 = Py_None;
n 573         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[1], tmp_assign_source_1); n 492         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[0], tmp_assign_source_1);
574     } 493     }
575     { 494     {
576         PyObject *tmp_assign_source_2; 495         PyObject *tmp_assign_source_2;
n 577         tmp_assign_source_2 = mod_consts[2]; n 496         tmp_assign_source_2 = mod_consts[1];
578         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[3], tmp_assign_source_2); 497         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[2], tmp_assign_source_2);
579     } 498     }
580     frame_82f8b6bedeb3c2e417b651aedd191d64 = MAKE_MODULE_FRAME(codeobj_82f8b6bedeb3c2e417b651aedd191d64, module___main__); 499     frame_82f8b6bedeb3c2e417b651aedd191d64 = MAKE_MODULE_FRAME(codeobj_82f8b6bedeb3c2e417b651aedd191d64, module___main__);
581 500
582     // Push the new frame as the currently active one, and we should be exclusively 501     // Push the new frame as the currently active one, and we should be exclusively
583     // owning it. 502     // owning it.
589         PyObject *tmp_assign_source_3; 508         PyObject *tmp_assign_source_3;
590         PyObject *tmp_name_value_1; 509         PyObject *tmp_name_value_1;
591         PyObject *tmp_globals_arg_value_1; 510         PyObject *tmp_globals_arg_value_1;
592         PyObject *tmp_locals_arg_value_1; 511         PyObject *tmp_locals_arg_value_1;
593         PyObject *tmp_fromlist_value_1; 512         PyObject *tmp_fromlist_value_1;
n 594         tmp_name_value_1 = mod_consts[4]; n 513         tmp_name_value_1 = mod_consts[3];
595         tmp_globals_arg_value_1 = (PyObject *)moduledict___main__; 514         tmp_globals_arg_value_1 = (PyObject *)moduledict___main__;
596         tmp_locals_arg_value_1 = Py_None; 515         tmp_locals_arg_value_1 = Py_None;
597         tmp_fromlist_value_1 = Py_None; 516         tmp_fromlist_value_1 = Py_None;
598         frame_82f8b6bedeb3c2e417b651aedd191d64->m_frame.f_lineno = 4; 517         frame_82f8b6bedeb3c2e417b651aedd191d64->m_frame.f_lineno = 4;
599         tmp_assign_source_3 = IMPORT_MODULE4(tstate, tmp_name_value_1, tmp_globals_arg_value_1, tmp_locals_arg_value_1, tmp_fromlist_value_1); 518         tmp_assign_source_3 = IMPORT_MODULE4(tstate, tmp_name_value_1, tmp_globals_arg_value_1, tmp_locals_arg_value_1, tmp_fromlist_value_1);
605 524
606             exception_lineno = 4; 525             exception_lineno = 4;
607 526
608             goto frame_exception_exit_1; 527             goto frame_exception_exit_1;
609         } 528         }
n 610         UPDATE_STRING_DICT1(moduledict___main__, (Nuitka_StringObject *)mod_consts[4], tmp_assign_source_3); n 529         UPDATE_STRING_DICT1(moduledict___main__, (Nuitka_StringObject *)mod_consts[3], tmp_assign_source_3);
611     } 530     }
612     { 531     {
613         PyObject *tmp_assign_source_4; 532         PyObject *tmp_assign_source_4;
614 533
615 534
619     } 538     }
620     { 539     {
621         PyObject *tmp_assign_source_5; 540         PyObject *tmp_assign_source_5;
622         PyObject *tmp_iter_arg_1; 541         PyObject *tmp_iter_arg_1;
623         PyObject *tmp_called_instance_1; 542         PyObject *tmp_called_instance_1;
n 624         tmp_called_instance_1 = GET_STRING_DICT_VALUE(moduledict___main__, (Nuitka_StringObject *)mod_consts[4]); n 543         tmp_called_instance_1 = GET_STRING_DICT_VALUE(moduledict___main__, (Nuitka_StringObject *)mod_consts[3]);
625 544
626         if (unlikely(tmp_called_instance_1 == NULL)) { 545         if (unlikely(tmp_called_instance_1 == NULL)) {
t 627             tmp_called_instance_1 = GET_MODULE_VARIABLE_VALUE_FALLBACK(tstate, mod_consts[4]); t 546             tmp_called_instance_1 = GET_MODULE_VARIABLE_VALUE_FALLBACK(tstate, mod_consts[3]);
628         } 547         }
629 548
630         assert(!(tmp_called_instance_1 == NULL)); 549         assert(!(tmp_called_instance_1 == NULL));
631         frame_82f8b6bedeb3c2e417b651aedd191d64->m_frame.f_lineno = 20; 550         frame_82f8b6bedeb3c2e417b651aedd191d64->m_frame.f_lineno = 20;
632         tmp_iter_arg_1 = CALL_METHOD_WITH_ARGS2( 551         tmp_iter_arg_1 = CALL_METHOD_WITH_ARGS2(