Construct BuiltinSumWithGenerator

Performance Diagrams

Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)20281876988.11538461538461257.0CPython 2.7126658892240.03846153846155349.7935683167241Nuitka (master)126660002391.96153846153845349.7922158872706Nuitka (develop)126660024543.8846153846154349.7921890823625Nuitka (factory)Construct BuiltinSumWithGeneratorTicks Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000280000000280000000300000000300000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)30208132688.11538461538461257.0CPython 3.5173182236240.03846153846155362.4449430016176Nuitka (master)173182059391.96153846153845362.44508779515274Nuitka (develop)173182035543.8846153846154362.4451074281744Nuitka (factory)Construct BuiltinSumWithGeneratorTicks

Source Code with Construct

empty = ()

def calledRepeatedly():
    # We measure making a generator iterator step or not.
    gen = (x for x in range(1000))

    # This should abort.
# construct_begin
    y = sum(gen)
# construct_alternative



    return y, gen

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

print("OK.")

Source Code without Construct

empty = ()

def calledRepeatedly():
    # We measure making a generator iterator step or not.
    gen = (x for x in range(1000))

    # This should abort.
# construct_begin

# construct_alternative
    y = gen
# construct_end

    return y, gen

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

print("OK.")

Context Diff of Source Code


Construct
Baseline
24     # We measure making a generator iterator step or not. 24     # We measure making a generator iterator step or not.
25     gen = (x for x in range(1000)) 25     gen = (x for x in range(1000))
26 26
27     # This should abort. 27     # This should abort.
28 # construct_begin 28 # construct_begin
n 29     y = sum(gen) n 29  
30 # construct_alternative 30 # construct_alternative
t 31   t 31     y = gen
32   32 # construct_end
33 33
34     return y, gen 34     return y, gen
35 35
36 import itertools 36 import itertools
37 for x in itertools.repeat(None, 500): 37 for x in itertools.repeat(None, 500):

Context Diff of Generated Code


Construct
Baseline
146 146
147     // Local variable declarations. 147     // Local variable declarations.
148     PyObject *var_y = NULL; 148     PyObject *var_y = NULL;
149     PyObject *var_gen = NULL; 149     PyObject *var_gen = NULL;
150     PyObject *tmp_genexpr_1__$0 = NULL; 150     PyObject *tmp_genexpr_1__$0 = NULL;
n 151     struct Nuitka_FrameObject *frame_b2d1e60c186bdcb561a7e3cb943611da; n
152     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
153     PyObject *exception_type = NULL;
154     PyObject *exception_value = NULL;
155     PyTracebackObject *exception_tb = NULL;
156     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
157     static struct Nuitka_FrameObject *cache_frame_b2d1e60c186bdcb561a7e3cb943611da = NULL;
158     PyObject *tmp_return_value = NULL; 151     PyObject *tmp_return_value = NULL;
n 159     PyObject *exception_keeper_type_1; n
160     PyObject *exception_keeper_value_1;
161     PyTracebackObject *exception_keeper_tb_1;
162     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
163 152
164     // Actual function body. 153     // Actual function body.
165     { 154     {
166         PyObject *tmp_assign_source_1; 155         PyObject *tmp_assign_source_1;
167         { 156         {
200         return NULL; 189         return NULL;
201         outline_result_1:; 190         outline_result_1:;
202         assert(var_gen == NULL); 191         assert(var_gen == NULL);
203         var_gen = tmp_assign_source_1; 192         var_gen = tmp_assign_source_1;
204     } 193     }
n n 194     {
195         PyObject *tmp_assign_source_3;
196         CHECK_OBJECT(var_gen);
197         tmp_assign_source_3 = var_gen;
198         assert(var_y == NULL);
199         Py_INCREF(tmp_assign_source_3);
200         var_y = tmp_assign_source_3;
201     }
205     // Tried code: 202     // Tried code:
n 206     MAKE_OR_REUSE_FRAME(cache_frame_b2d1e60c186bdcb561a7e3cb943611da, codeobj_b2d1e60c186bdcb561a7e3cb943611da, module___main__, sizeof(void *)+sizeof(void *)); n
207     frame_b2d1e60c186bdcb561a7e3cb943611da = cache_frame_b2d1e60c186bdcb561a7e3cb943611da;
208  
209     // Push the new frame as the currently active one.
210     pushFrameStack(frame_b2d1e60c186bdcb561a7e3cb943611da);
211  
212     // Mark the frame object as in use, ref count 1 will be up for reuse.
213     assert(Py_REFCNT(frame_b2d1e60c186bdcb561a7e3cb943611da) == 2); // Frame stack
214  
215     // Framed code:
216     {
217         PyObject *tmp_assign_source_3;
218         PyObject *tmp_sum_sequence_1;
219         CHECK_OBJECT(var_gen);
220         tmp_sum_sequence_1 = var_gen;
221         tmp_assign_source_3 = BUILTIN_SUM1( tmp_sum_sequence_1 );
222         if ( tmp_assign_source_3 == NULL )
223         {
224             assert(ERROR_OCCURRED());
225  
226             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
227  
228  
229             exception_lineno = 29;
230             type_description_1 = "oo";
231             goto frame_exception_exit_1;
232         }
233         assert(var_y == NULL);
234         var_y = tmp_assign_source_3;
235     }
236  
237 #if 0
238     RESTORE_FRAME_EXCEPTION(frame_b2d1e60c186bdcb561a7e3cb943611da);
239 #endif
240  
241     // Put the previous frame back on top.
242     popFrameStack();
243  
244     goto frame_no_exception_1;
245  
246     frame_exception_exit_1:;
247  
248 #if 0
249     RESTORE_FRAME_EXCEPTION(frame_b2d1e60c186bdcb561a7e3cb943611da);
250 #endif
251  
252     if (exception_tb == NULL) {
253         exception_tb = MAKE_TRACEBACK( frame_b2d1e60c186bdcb561a7e3cb943611da, exception_lineno );
254     }
255     else if (exception_tb->tb_frame != &frame_b2d1e60c186bdcb561a7e3cb943611da->m_frame) {
256         exception_tb = ADD_TRACEBACK(exception_tb, frame_b2d1e60c186bdcb561a7e3cb943611da, exception_lineno);
257     }
258  
259     // Attachs locals to frame if any.
260     Nuitka_Frame_AttachLocals(
261         (struct Nuitka_FrameObject *)frame_b2d1e60c186bdcb561a7e3cb943611da,
262         type_description_1,
263         var_y,
264         var_gen
265     );
266  
267  
268     // Release cached frame.
269     if (frame_b2d1e60c186bdcb561a7e3cb943611da == cache_frame_b2d1e60c186bdcb561a7e3cb943611da) {
270         Py_DECREF(frame_b2d1e60c186bdcb561a7e3cb943611da);
271     }
272     cache_frame_b2d1e60c186bdcb561a7e3cb943611da = NULL;
273  
274     assertFrameObject(frame_b2d1e60c186bdcb561a7e3cb943611da);
275  
276     // Put the previous frame back on top.
277     popFrameStack();
278  
279     // Return the error.
280     goto try_except_handler_2;
281  
282     frame_no_exception_1:;
283     { 203     {
284         PyObject *tmp_tuple_element_1; 204         PyObject *tmp_tuple_element_1;
285         CHECK_OBJECT(var_y); 205         CHECK_OBJECT(var_y);
286         tmp_tuple_element_1 = var_y; 206         tmp_tuple_element_1 = var_y;
287         tmp_return_value = PyTuple_New( 2 ); 207         tmp_return_value = PyTuple_New( 2 );
305     CHECK_OBJECT((PyObject *)var_gen); 225     CHECK_OBJECT((PyObject *)var_gen);
306     Py_DECREF(var_gen); 226     Py_DECREF(var_gen);
307     var_gen = NULL; 227     var_gen = NULL;
308 228
309     goto function_return_exit; 229     goto function_return_exit;
n 310     // Exception handler code: n
311     try_except_handler_2:;
312     exception_keeper_type_1 = exception_type;
313     exception_keeper_value_1 = exception_value;
314     exception_keeper_tb_1 = exception_tb;
315     exception_keeper_lineno_1 = exception_lineno;
316     exception_type = NULL;
317     exception_value = NULL;
318     exception_tb = NULL;
319     exception_lineno = 0;
320  
321     CHECK_OBJECT((PyObject *)var_gen);
322     Py_DECREF(var_gen);
323     var_gen = NULL;
324  
325     // Re-raise.
326     exception_type = exception_keeper_type_1;
327     exception_value = exception_keeper_value_1;
328     exception_tb = exception_keeper_tb_1;
329     exception_lineno = exception_keeper_lineno_1;
330  
331     goto function_exception_exit;
332     // End of try: 230     // End of try:
333 231
334     // Return statement must have exited already. 232     // Return statement must have exited already.
335     NUITKA_CANNOT_GET_HERE(__main__$$$function_1_calledRepeatedly); 233     NUITKA_CANNOT_GET_HERE(__main__$$$function_1_calledRepeatedly);
336     return NULL; 234     return NULL;
337 235
t 338 function_exception_exit: t
339     assert(exception_type);
340     RESTORE_ERROR_OCCURRED(exception_type, exception_value, exception_tb);
341  
342     return NULL;
343 236
344 function_return_exit: 237 function_return_exit:
345    // Function cleanup code if any. 238    // Function cleanup code if any.
346 239
347 240