Construct FunctionCreationLocal

Performance Diagrams

Construct FunctionCreationLocal 00200000020000004000000400000060000006000000800000080000001000000010000000120000001200000014000000140000001600000016000000180000001800000020000000200000002200000022000000240000002400000026000000260000002800000028000000CPython 3.10Nuitka (main)Nuitka (develop)Nuitka (factory)2913130988.95192307692307257.0CPython 3.1010153248242.31730769230768417.98730212463954Nuitka (main)10153958395.6826923076923417.9812793289225Nuitka (develop)10153958549.0480769230769417.9812793289225Nuitka (factory)Construct FunctionCreationLocalTicks Construct FunctionCreationLocal 00200000020000004000000400000060000006000000800000080000001000000010000000120000001200000014000000140000001600000016000000180000001800000020000000200000002200000022000000CPython 3.8Nuitka (main)Nuitka (develop)Nuitka (factory)2207079188.95192307692307257.0CPython 3.810217450242.31730769230768389.7158106926167Nuitka (main)10222561395.6826923076923389.6585854336412Nuitka (develop)10222561549.0480769230769389.6585854336412Nuitka (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_fbda7d4859dc54d62dbd591de9f74869; 81 static PyCodeObject *codeobj_fbda7d4859dc54d62dbd591de9f74869;
82 static PyCodeObject *codeobj_1dacf538eab0697bba9a9f3c00a98988; 82 static PyCodeObject *codeobj_1dacf538eab0697bba9a9f3c00a98988;
n 83 static PyCodeObject *codeobj_ca7e960635b32d4a8911e2a222626622; 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_fbda7d4859dc54d62dbd591de9f74869 = MAKE_CODE_OBJECT(module_filename_obj, 1, CO_NOFREE, mod_consts[10], mod_consts[10], NULL, NULL, 0, 0, 0); 88     codeobj_fbda7d4859dc54d62dbd591de9f74869 = MAKE_CODE_OBJECT(module_filename_obj, 1, CO_NOFREE, mod_consts[10], mod_consts[10], NULL, NULL, 0, 0, 0);
90     codeobj_main = codeobj_fbda7d4859dc54d62dbd591de9f74869; 89     codeobj_main = codeobj_fbda7d4859dc54d62dbd591de9f74869;
91     codeobj_1dacf538eab0697bba9a9f3c00a98988 = 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_1dacf538eab0697bba9a9f3c00a98988 = 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_ca7e960635b32d4a8911e2a222626622 = 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_1dacf538eab0697bba9a9f3c00a98988, 106         codeobj_1dacf538eab0697bba9a9f3c00a98988,
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_ca7e960635b32d4a8911e2a222626622,
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;
570 489
571     // Module code. 490     // Module code.
572     { 491     {
573         PyObject *tmp_assign_source_1; 492         PyObject *tmp_assign_source_1;
574         tmp_assign_source_1 = Py_None; 493         tmp_assign_source_1 = Py_None;
n 575         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[1], tmp_assign_source_1); n 494         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[0], tmp_assign_source_1);
576     } 495     }
577     { 496     {
578         PyObject *tmp_assign_source_2; 497         PyObject *tmp_assign_source_2;
n 579         tmp_assign_source_2 = mod_consts[2]; n 498         tmp_assign_source_2 = mod_consts[1];
580         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[3], tmp_assign_source_2); 499         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[2], tmp_assign_source_2);
581     } 500     }
582     frame_fbda7d4859dc54d62dbd591de9f74869 = MAKE_MODULE_FRAME(codeobj_fbda7d4859dc54d62dbd591de9f74869, module___main__); 501     frame_fbda7d4859dc54d62dbd591de9f74869 = MAKE_MODULE_FRAME(codeobj_fbda7d4859dc54d62dbd591de9f74869, module___main__);
583 502
584     // Push the new frame as the currently active one, and we should be exclusively 503     // Push the new frame as the currently active one, and we should be exclusively
585     // owning it. 504     // owning it.
591         PyObject *tmp_assign_source_3; 510         PyObject *tmp_assign_source_3;
592         PyObject *tmp_name_value_1; 511         PyObject *tmp_name_value_1;
593         PyObject *tmp_globals_arg_value_1; 512         PyObject *tmp_globals_arg_value_1;
594         PyObject *tmp_locals_arg_value_1; 513         PyObject *tmp_locals_arg_value_1;
595         PyObject *tmp_fromlist_value_1; 514         PyObject *tmp_fromlist_value_1;
n 596         tmp_name_value_1 = mod_consts[4]; n 515         tmp_name_value_1 = mod_consts[3];
597         tmp_globals_arg_value_1 = (PyObject *)moduledict___main__; 516         tmp_globals_arg_value_1 = (PyObject *)moduledict___main__;
598         tmp_locals_arg_value_1 = Py_None; 517         tmp_locals_arg_value_1 = Py_None;
599         tmp_fromlist_value_1 = Py_None; 518         tmp_fromlist_value_1 = Py_None;
600         frame_fbda7d4859dc54d62dbd591de9f74869->m_frame.f_lineno = 4; 519         frame_fbda7d4859dc54d62dbd591de9f74869->m_frame.f_lineno = 4;
601         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); 520         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);
607 526
608             exception_lineno = 4; 527             exception_lineno = 4;
609 528
610             goto frame_exception_exit_1; 529             goto frame_exception_exit_1;
611         } 530         }
n 612         UPDATE_STRING_DICT1(moduledict___main__, (Nuitka_StringObject *)mod_consts[4], tmp_assign_source_3); n 531         UPDATE_STRING_DICT1(moduledict___main__, (Nuitka_StringObject *)mod_consts[3], tmp_assign_source_3);
613     } 532     }
614     { 533     {
615         PyObject *tmp_assign_source_4; 534         PyObject *tmp_assign_source_4;
616 535
617 536
621     } 540     }
622     { 541     {
623         PyObject *tmp_assign_source_5; 542         PyObject *tmp_assign_source_5;
624         PyObject *tmp_iter_arg_1; 543         PyObject *tmp_iter_arg_1;
625         PyObject *tmp_called_instance_1; 544         PyObject *tmp_called_instance_1;
n 626         tmp_called_instance_1 = GET_STRING_DICT_VALUE(moduledict___main__, (Nuitka_StringObject *)mod_consts[4]); n 545         tmp_called_instance_1 = GET_STRING_DICT_VALUE(moduledict___main__, (Nuitka_StringObject *)mod_consts[3]);
627 546
628         if (unlikely(tmp_called_instance_1 == NULL)) { 547         if (unlikely(tmp_called_instance_1 == NULL)) {
t 629             tmp_called_instance_1 = GET_MODULE_VARIABLE_VALUE_FALLBACK(tstate, mod_consts[4]); t 548             tmp_called_instance_1 = GET_MODULE_VARIABLE_VALUE_FALLBACK(tstate, mod_consts[3]);
630         } 549         }
631 550
632         assert(!(tmp_called_instance_1 == NULL)); 551         assert(!(tmp_called_instance_1 == NULL));
633         frame_fbda7d4859dc54d62dbd591de9f74869->m_frame.f_lineno = 20; 552         frame_fbda7d4859dc54d62dbd591de9f74869->m_frame.f_lineno = 20;
634         tmp_iter_arg_1 = CALL_METHOD_WITH_ARGS2( 553         tmp_iter_arg_1 = CALL_METHOD_WITH_ARGS2(