Construct CallLambdaExpressionDirectly

Performance Diagrams

Construct CallLambdaExpressionDirectly 0010000000100000002000000020000000300000003000000040000000400000005000000050000000CPython 3.10Nuitka (main)Nuitka (develop)Nuitka (factory)5637142588.95192307692307254.82677014734446CPython 3.10-499885242.31730769230768501.94099895350183Nuitka (main)-500151395.6826923076923501.94215476272905Nuitka (develop)-499842549.0480769230769501.9408121121606Nuitka (factory)Construct CallLambdaExpressionDirectlyTicks Construct CallLambdaExpressionDirectly 001000000010000000200000002000000030000000300000004000000040000000CPython 3.8Nuitka (main)Nuitka (develop)Nuitka (factory)4905921488.95192307692307254.50733137590944CPython 3.8-499906242.31730769230768501.62271599129406Nuitka (main)-497918395.6826923076923501.61280327725444Nuitka (develop)-499887549.0480769230769501.6226212520754Nuitka (factory)Construct CallLambdaExpressionDirectlyTicks Construct CallLambdaExpressionDirectly 00100000001000000020000000200000003000000030000000CPython 2.7Nuitka (main)Nuitka (develop)Nuitka (factory)3996438288.95192307692307253.94647117855828CPython 2.7-500006242.31730769230768501.0618557939429Nuitka (main)-500002395.6826923076923501.06183136600544Nuitka (develop)-500002549.0480769230769501.06183136600544Nuitka (factory)Construct CallLambdaExpressionDirectlyTicks

Source Code with Construct

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

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
6 import itertools 6 import itertools
7 7
8 8
9 def calledRepeatedly(): 9 def calledRepeatedly():
10     # construct_begin 10     # construct_begin
n 11     return (lambda x: x)(7) n 11  
12     # construct_alternative 12     # construct_alternative
n n 13     return 7
13 14
14 15
t 15   t 16 # construct_end
16  
17 17
18 for x in itertools.repeat(None, 50000): 18 for x in itertools.repeat(None, 50000):
19     calledRepeatedly() 19     calledRepeatedly()
20 20
21 print("OK.") 21 print("OK.")

Context Diff of Generated Code


Construct
Baseline
82 static PyCodeObject *codeobj_4b14d62854911cfd37f7ac083ec060b0; 82 static PyCodeObject *codeobj_4b14d62854911cfd37f7ac083ec060b0;
83 /* For use in "MainProgram.c". */ 83 /* For use in "MainProgram.c". */
84 PyCodeObject *codeobj_main = NULL; 84 PyCodeObject *codeobj_main = NULL;
85 85
86 static void createModuleCodeObjects(void) { 86 static void createModuleCodeObjects(void) {
n 87     module_filename_obj = mod_consts[2]; CHECK_OBJECT(module_filename_obj); n 87     module_filename_obj = mod_consts[1]; CHECK_OBJECT(module_filename_obj);
88     codeobj_7ec2341252c9420f2b89f90a04fdf6b1 = MAKE_CODE_OBJECT(module_filename_obj, 1, CO_NOFREE | CO_FUTURE_PRINT_FUNCTION, mod_consts[12], mod_consts[12], NULL, NULL, 0, 0, 0); 88     codeobj_7ec2341252c9420f2b89f90a04fdf6b1 = MAKE_CODE_OBJECT(module_filename_obj, 1, CO_NOFREE | CO_FUTURE_PRINT_FUNCTION, mod_consts[12], mod_consts[12], NULL, NULL, 0, 0, 0);
89     codeobj_main = codeobj_7ec2341252c9420f2b89f90a04fdf6b1; 89     codeobj_main = codeobj_7ec2341252c9420f2b89f90a04fdf6b1;
90     codeobj_4b14d62854911cfd37f7ac083ec060b0 = MAKE_CODE_OBJECT(module_filename_obj, 9, CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE | CO_FUTURE_PRINT_FUNCTION, mod_consts[6], mod_consts[6], NULL, NULL, 0, 0, 0); 90     codeobj_4b14d62854911cfd37f7ac083ec060b0 = MAKE_CODE_OBJECT(module_filename_obj, 9, CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE | CO_FUTURE_PRINT_FUNCTION, mod_consts[6], mod_consts[6], NULL, NULL, 0, 0, 0);
91 } 91 }
92 92
93 // The module function declarations. 93 // The module function declarations.
n 94 NUITKA_LOCAL_MODULE PyObject *impl___main__$$$function__1_calledRepeatedly$$$function__1_lambda(PyThreadState *tstate, PyObject **python_pars); n
95  
96  
97 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly(); 94 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly();
98 95
99 96
100 // The module function definitions. 97 // The module function definitions.
n 101 static PyObject *impl___main__$$$function__1_calledRepeatedly(PyThreadState *tstate, struct Nuitka_FunctionObject const *self, PyObject **python_pars) { n
102     // Preserve error status for checks
103 #ifndef __NUITKA_NO_ASSERT__
104     NUITKA_MAY_BE_UNUSED bool had_error = HAS_ERROR_OCCURRED(tstate);
105 #endif
106  
107     // Local variable declarations.
108     PyObject *tmp_return_value = NULL;
109  
110     // Actual function body.
111     {
112         PyObject *tmp_dircall_arg1_1;
113         tmp_dircall_arg1_1 = mod_consts[0];
114         Py_INCREF(tmp_dircall_arg1_1);
115  
116         {
117             PyObject *dir_call_args[] = {tmp_dircall_arg1_1};
118             tmp_return_value = impl___main__$$$function__1_calledRepeatedly$$$function__1_lambda(tstate, dir_call_args);
119         }
120         assert(!(tmp_return_value == NULL));
121         goto function_return_exit;
122     }
123  
124     NUITKA_CANNOT_GET_HERE("Return statement must have exited already.");
125     return NULL;
126  
127  
128 function_return_exit:
129    // Function cleanup code if any.
130  
131  
132    // Actual function exit with return value, making sure we did not make
133    // the error status worse despite non-NULL return.
134    CHECK_OBJECT(tmp_return_value);
135    assert(had_error || !HAS_ERROR_OCCURRED(tstate));
136    return tmp_return_value;
137 }
138  
139  
140 NUITKA_LOCAL_MODULE PyObject *impl___main__$$$function__1_calledRepeatedly$$$function__1_lambda(PyThreadState *tstate, PyObject **python_pars) {
141 #ifndef __NUITKA_NO_ASSERT__
142     NUITKA_MAY_BE_UNUSED bool had_error = HAS_ERROR_OCCURRED(tstate);
143     assert(!had_error); // Do not enter inlined functions with error set.
144 #endif
145  
146     // Local variable declarations.
147     PyObject *par_x = python_pars[0];
148     PyObject *tmp_return_value = NULL;
149  
150     // Actual function body.
151     CHECK_OBJECT(par_x);
152     tmp_return_value = par_x;
153     Py_INCREF(tmp_return_value);
154     goto function_return_exit;
155  
156     NUITKA_CANNOT_GET_HERE("Return statement must have exited already.");
157     return NULL;
158  
159  
160 function_return_exit:
161    // Function cleanup code if any.
162     CHECK_OBJECT(par_x);
163     Py_DECREF(par_x);
164  
165    // Actual function exit with return value, making sure we did not make
166    // the error status worse despite non-NULL return.
167    CHECK_OBJECT(tmp_return_value);
168    assert(had_error || !HAS_ERROR_OCCURRED(tstate));
169    return tmp_return_value;
170 }
171  
172  
173 98
174 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly() { 99 static PyObject *MAKE_FUNCTION___main__$$$function__1_calledRepeatedly() {
175     struct Nuitka_FunctionObject *result = Nuitka_Function_New( 100     struct Nuitka_FunctionObject *result = Nuitka_Function_New(
n 176         impl___main__$$$function__1_calledRepeatedly, n 101         NULL,
177         mod_consts[6], 102         mod_consts[6],
178 #if PYTHON_VERSION >= 0x300 103 #if PYTHON_VERSION >= 0x300
179         NULL, 104         NULL,
180 #endif 105 #endif
181         codeobj_4b14d62854911cfd37f7ac083ec060b0, 106         codeobj_4b14d62854911cfd37f7ac083ec060b0,
187         module___main__, 112         module___main__,
188         NULL, 113         NULL,
189         NULL, 114         NULL,
190         0 115         0
191     ); 116     );
n 192   n 117     Nuitka_Function_EnableConstReturnGeneric(result, mod_consts[5]);
193 118
194     return (PyObject *)result; 119     return (PyObject *)result;
195 } 120 }
196 121
197 122
207 // 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
208 // in another process, useful for multiprocessing extensions like dill 133 // in another process, useful for multiprocessing extensions like dill
209 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);
210 135
211 static function_impl_code const function_table___main__[] = { 136 static function_impl_code const function_table___main__[] = {
n 212     impl___main__$$$function__1_calledRepeatedly, n 137  
213     NULL 138     NULL
214 }; 139 };
215 140
216 static PyObject *_reduce_compiled_function(PyObject *self, PyObject *args, PyObject *kwds) { 141 static PyObject *_reduce_compiled_function(PyObject *self, PyObject *args, PyObject *kwds) {
217     PyObject *func; 142     PyObject *func;
560 485
561     // Module code. 486     // Module code.
562     { 487     {
563         PyObject *tmp_assign_source_1; 488         PyObject *tmp_assign_source_1;
564         tmp_assign_source_1 = Py_None; 489         tmp_assign_source_1 = Py_None;
n 565         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[1], tmp_assign_source_1); n 490         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[0], tmp_assign_source_1);
566     } 491     }
567     { 492     {
568         PyObject *tmp_assign_source_2; 493         PyObject *tmp_assign_source_2;
n 569         tmp_assign_source_2 = mod_consts[2]; n 494         tmp_assign_source_2 = mod_consts[1];
570         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[3], tmp_assign_source_2); 495         UPDATE_STRING_DICT0(moduledict___main__, (Nuitka_StringObject *)mod_consts[2], tmp_assign_source_2);
571     } 496     }
572     { 497     {
573         PyObject *tmp_assign_source_3; 498         PyObject *tmp_assign_source_3;
574         { 499         {
575             PyObject *hard_module = IMPORT_HARD___FUTURE__(); 500             PyObject *hard_module = IMPORT_HARD___FUTURE__();
n 576             tmp_assign_source_3 = LOOKUP_ATTRIBUTE(tstate, hard_module, mod_consts[4]); n 501             tmp_assign_source_3 = LOOKUP_ATTRIBUTE(tstate, hard_module, mod_consts[3]);
577         } 502         }
578         assert(!(tmp_assign_source_3 == NULL)); 503         assert(!(tmp_assign_source_3 == NULL));
n 579         UPDATE_STRING_DICT1(moduledict___main__, (Nuitka_StringObject *)mod_consts[4], tmp_assign_source_3); n 504         UPDATE_STRING_DICT1(moduledict___main__, (Nuitka_StringObject *)mod_consts[3], tmp_assign_source_3);
580     } 505     }
581     frame_7ec2341252c9420f2b89f90a04fdf6b1 = MAKE_MODULE_FRAME(codeobj_7ec2341252c9420f2b89f90a04fdf6b1, module___main__); 506     frame_7ec2341252c9420f2b89f90a04fdf6b1 = MAKE_MODULE_FRAME(codeobj_7ec2341252c9420f2b89f90a04fdf6b1, module___main__);
582 507
583     // Push the new frame as the currently active one, and we should be exclusively 508     // Push the new frame as the currently active one, and we should be exclusively
584     // owning it. 509     // owning it.
590         PyObject *tmp_assign_source_4; 515         PyObject *tmp_assign_source_4;
591         PyObject *tmp_name_value_1; 516         PyObject *tmp_name_value_1;
592         PyObject *tmp_globals_arg_value_1; 517         PyObject *tmp_globals_arg_value_1;
593         PyObject *tmp_locals_arg_value_1; 518         PyObject *tmp_locals_arg_value_1;
594         PyObject *tmp_fromlist_value_1; 519         PyObject *tmp_fromlist_value_1;
n 595         tmp_name_value_1 = mod_consts[5]; n 520         tmp_name_value_1 = mod_consts[4];
596         tmp_globals_arg_value_1 = (PyObject *)moduledict___main__; 521         tmp_globals_arg_value_1 = (PyObject *)moduledict___main__;
597         tmp_locals_arg_value_1 = Py_None; 522         tmp_locals_arg_value_1 = Py_None;
598         tmp_fromlist_value_1 = Py_None; 523         tmp_fromlist_value_1 = Py_None;
599         frame_7ec2341252c9420f2b89f90a04fdf6b1->m_frame.f_lineno = 6; 524         frame_7ec2341252c9420f2b89f90a04fdf6b1->m_frame.f_lineno = 6;
600         tmp_assign_source_4 = IMPORT_MODULE4(tstate, tmp_name_value_1, tmp_globals_arg_value_1, tmp_locals_arg_value_1, tmp_fromlist_value_1); 525         tmp_assign_source_4 = IMPORT_MODULE4(tstate, tmp_name_value_1, tmp_globals_arg_value_1, tmp_locals_arg_value_1, tmp_fromlist_value_1);
606 531
607             exception_lineno = 6; 532             exception_lineno = 6;
608 533
609             goto frame_exception_exit_1; 534             goto frame_exception_exit_1;
610         } 535         }
n 611         UPDATE_STRING_DICT1(moduledict___main__, (Nuitka_StringObject *)mod_consts[5], tmp_assign_source_4); n 536         UPDATE_STRING_DICT1(moduledict___main__, (Nuitka_StringObject *)mod_consts[4], tmp_assign_source_4);
612     } 537     }
613     { 538     {
614         PyObject *tmp_assign_source_5; 539         PyObject *tmp_assign_source_5;
615 540
616 541
620     } 545     }
621     { 546     {
622         PyObject *tmp_assign_source_6; 547         PyObject *tmp_assign_source_6;
623         PyObject *tmp_iter_arg_1; 548         PyObject *tmp_iter_arg_1;
624         PyObject *tmp_called_instance_1; 549         PyObject *tmp_called_instance_1;
n 625         tmp_called_instance_1 = GET_STRING_DICT_VALUE(moduledict___main__, (Nuitka_StringObject *)mod_consts[5]); n 550         tmp_called_instance_1 = GET_STRING_DICT_VALUE(moduledict___main__, (Nuitka_StringObject *)mod_consts[4]);
626 551
627         if (unlikely(tmp_called_instance_1 == NULL)) { 552         if (unlikely(tmp_called_instance_1 == NULL)) {
t 628             tmp_called_instance_1 = GET_MODULE_VARIABLE_VALUE_FALLBACK(tstate, mod_consts[5]); t 553             tmp_called_instance_1 = GET_MODULE_VARIABLE_VALUE_FALLBACK(tstate, mod_consts[4]);
629         } 554         }
630 555
631         assert(!(tmp_called_instance_1 == NULL)); 556         assert(!(tmp_called_instance_1 == NULL));
632         frame_7ec2341252c9420f2b89f90a04fdf6b1->m_frame.f_lineno = 18; 557         frame_7ec2341252c9420f2b89f90a04fdf6b1->m_frame.f_lineno = 18;
633         tmp_iter_arg_1 = CALL_METHOD_WITH_ARGS2( 558         tmp_iter_arg_1 = CALL_METHOD_WITH_ARGS2(