Construct BuiltinSumWithGenerator

Performance Diagrams

Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)19085008988.11538461538461296.634860478224CPython 2.7227308049240.03846153846155257.0Nuitka (master)226808584391.96153846153845257.5429877477718Nuitka (develop)226809145543.8846153846154257.5423778629421Nuitka (factory)Construct BuiltinSumWithGeneratorTicks Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000280000000280000000300000000300000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)30373505288.11538461538461257.00000000000006CPython 3.5270547668240.03846153846155284.00087825733885Nuitka (master)271047784391.96153846153845283.593989566427Nuitka (develop)271047650543.8846153846154283.59409858730334Nuitka (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
149 149
150     // Local variable declarations. 150     // Local variable declarations.
151     PyObject *var_gen = NULL; 151     PyObject *var_gen = NULL;
152     PyObject *var_y = NULL; 152     PyObject *var_y = NULL;
153     PyObject *tmp_genexpr_1__$0 = NULL; 153     PyObject *tmp_genexpr_1__$0 = NULL;
n 154     PyObject *exception_type = NULL; n
155     PyObject *exception_value = NULL;
156     PyTracebackObject *exception_tb = NULL;
157     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
158     PyObject *exception_keeper_type_1;
159     PyObject *exception_keeper_value_1;
160     PyTracebackObject *exception_keeper_tb_1;
161     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
162     PyObject *tmp_assign_source_1; 154     PyObject *tmp_assign_source_1;
163     PyObject *tmp_assign_source_2; 155     PyObject *tmp_assign_source_2;
164     PyObject *tmp_assign_source_3; 156     PyObject *tmp_assign_source_3;
165     PyObject *tmp_iter_arg_1; 157     PyObject *tmp_iter_arg_1;
166     PyObject *tmp_outline_return_value_1; 158     PyObject *tmp_outline_return_value_1;
167     PyObject *tmp_return_value; 159     PyObject *tmp_return_value;
n 168     PyObject *tmp_sum_sequence_1; n
169     PyObject *tmp_tuple_element_1; 160     PyObject *tmp_tuple_element_1;
n 170     static struct Nuitka_FrameObject *cache_frame_5891894c5aa72da800aa86281c3f5a42 = NULL; n
171  
172     struct Nuitka_FrameObject *frame_5891894c5aa72da800aa86281c3f5a42;
173  
174     char const *type_description;
175     tmp_return_value = NULL; 161     tmp_return_value = NULL;
176     tmp_outline_return_value_1 = NULL; 162     tmp_outline_return_value_1 = NULL;
177 163
178     // Actual function code. 164     // Actual function code.
179     tmp_iter_arg_1 = const_xrange_0_1000; 165     tmp_iter_arg_1 = const_xrange_0_1000;
220     outline_result_1:; 206     outline_result_1:;
221     tmp_assign_source_1 = tmp_outline_return_value_1; 207     tmp_assign_source_1 = tmp_outline_return_value_1;
222     assert( var_gen == NULL ); 208     assert( var_gen == NULL );
223     var_gen = tmp_assign_source_1; 209     var_gen = tmp_assign_source_1;
224 210
n n 211     tmp_assign_source_3 = var_gen;
212  
213     CHECK_OBJECT( tmp_assign_source_3 );
214     assert( var_y == NULL );
215     Py_INCREF( tmp_assign_source_3 );
216     var_y = tmp_assign_source_3;
217  
225     // Tried code: 218     // Tried code:
n 226     MAKE_OR_REUSE_FRAME( cache_frame_5891894c5aa72da800aa86281c3f5a42, codeobj_5891894c5aa72da800aa86281c3f5a42, module___main__, sizeof(PyObject *)+sizeof(PyObject *) ); n
227     frame_5891894c5aa72da800aa86281c3f5a42 = cache_frame_5891894c5aa72da800aa86281c3f5a42;
228  
229     // Push the new frame as the currently active one.
230     pushFrameStack( frame_5891894c5aa72da800aa86281c3f5a42 );
231  
232     // Mark the frame object as in use, ref count 1 will be up for reuse.
233     assert( Py_REFCNT( frame_5891894c5aa72da800aa86281c3f5a42 ) == 2 ); // Frame stack
234  
235     // Framed code:
236     tmp_sum_sequence_1 = var_gen;
237  
238     CHECK_OBJECT( tmp_sum_sequence_1 );
239     tmp_assign_source_3 = BUILTIN_SUM1( tmp_sum_sequence_1 );
240     if ( tmp_assign_source_3 == NULL )
241     {
242         assert( ERROR_OCCURRED() );
243  
244         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
245  
246  
247         exception_lineno = 29;
248         type_description = "oo";
249         goto frame_exception_exit_1;
250     }
251     assert( var_y == NULL );
252     var_y = tmp_assign_source_3;
253  
254  
255 #if 0
256     RESTORE_FRAME_EXCEPTION( frame_5891894c5aa72da800aa86281c3f5a42 );
257 #endif
258  
259     // Put the previous frame back on top.
260     popFrameStack();
261  
262     goto frame_no_exception_1;
263  
264     frame_exception_exit_1:;
265  
266 #if 0
267     RESTORE_FRAME_EXCEPTION( frame_5891894c5aa72da800aa86281c3f5a42 );
268 #endif
269  
270     if ( exception_tb == NULL )
271     {
272         exception_tb = MAKE_TRACEBACK( frame_5891894c5aa72da800aa86281c3f5a42, exception_lineno );
273     }
274     else if ( exception_tb->tb_frame != &frame_5891894c5aa72da800aa86281c3f5a42->m_frame )
275     {
276         exception_tb = ADD_TRACEBACK( exception_tb, frame_5891894c5aa72da800aa86281c3f5a42, exception_lineno );
277     }
278  
279     Nuitka_Frame_AttachLocals( (struct Nuitka_FrameObject *)frame_5891894c5aa72da800aa86281c3f5a42, type_description ,var_gen, var_y );
280  
281     // Release cached frame.
282     if ( frame_5891894c5aa72da800aa86281c3f5a42 == cache_frame_5891894c5aa72da800aa86281c3f5a42 )
283     {
284         Py_DECREF( frame_5891894c5aa72da800aa86281c3f5a42 );
285     }
286     cache_frame_5891894c5aa72da800aa86281c3f5a42 = NULL;
287  
288     assertFrameObject( frame_5891894c5aa72da800aa86281c3f5a42 );
289  
290  
291     // Put the previous frame back on top.
292     popFrameStack();
293  
294     // Return the error.
295     goto try_except_handler_2;
296  
297     frame_no_exception_1:;
298  
299     tmp_return_value = PyTuple_New( 2 ); 219     tmp_return_value = PyTuple_New( 2 );
300     tmp_tuple_element_1 = var_y; 220     tmp_tuple_element_1 = var_y;
301 221
302     CHECK_OBJECT( tmp_tuple_element_1 ); 222     CHECK_OBJECT( tmp_tuple_element_1 );
303     Py_INCREF( tmp_tuple_element_1 ); 223     Py_INCREF( tmp_tuple_element_1 );
319 239
320     Py_XDECREF( var_y ); 240     Py_XDECREF( var_y );
321     var_y = NULL; 241     var_y = NULL;
322 242
323     goto function_return_exit; 243     goto function_return_exit;
n 324     // Exception handler code: n
325     try_except_handler_2:;
326     exception_keeper_type_1 = exception_type;
327     exception_keeper_value_1 = exception_value;
328     exception_keeper_tb_1 = exception_tb;
329     exception_keeper_lineno_1 = exception_lineno;
330     exception_type = NULL;
331     exception_value = NULL;
332     exception_tb = NULL;
333     exception_lineno = 0;
334  
335     CHECK_OBJECT( (PyObject *)var_gen );
336     Py_DECREF( var_gen );
337     var_gen = NULL;
338  
339     // Re-raise.
340     exception_type = exception_keeper_type_1;
341     exception_value = exception_keeper_value_1;
342     exception_tb = exception_keeper_tb_1;
343     exception_lineno = exception_keeper_lineno_1;
344  
345     goto function_exception_exit;
346     // End of try: 244     // End of try:
347 245
348     // Return statement must have exited already. 246     // Return statement must have exited already.
349     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 247     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
350     return NULL; 248     return NULL;
351 249
t 352 function_exception_exit: t
353     assert( exception_type );
354     RESTORE_ERROR_OCCURRED( exception_type, exception_value, exception_tb );
355  
356     return NULL;
357     function_return_exit: 250     function_return_exit:
358 251
359     CHECK_OBJECT( tmp_return_value ); 252     CHECK_OBJECT( tmp_return_value );
360     assert( had_error || !ERROR_OCCURRED() ); 253     assert( had_error || !ERROR_OCCURRED() );
361     return tmp_return_value; 254     return tmp_return_value;