Construct BuiltinSumWithGenerator

Performance Diagrams

Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)19085008988.11538461538461296.18492789253247CPython 2.7226811068240.03846153846155257.00557604181944Nuitka (master)226815874391.96153846153845257.00033992283073Nuitka (develop)226816186543.8846153846154257.0Nuitka (factory)Construct BuiltinSumWithGeneratorTicks Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000280000000280000000300000000300000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)30373505288.11538461538461257.00000000000006CPython 3.5271040968240.03846153846155283.5995349865241Nuitka (master)271046706391.96153846153845283.59486661496936Nuitka (develop)271040456543.8846153846154283.59995154390225Nuitka (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_d6f61ec0523939d4dfd5f12a04432151 = NULL; n
171  
172     struct Nuitka_FrameObject *frame_d6f61ec0523939d4dfd5f12a04432151;
173  
174     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
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_d6f61ec0523939d4dfd5f12a04432151, codeobj_d6f61ec0523939d4dfd5f12a04432151, module___main__, sizeof(void *)+sizeof(void *) ); n
227     frame_d6f61ec0523939d4dfd5f12a04432151 = cache_frame_d6f61ec0523939d4dfd5f12a04432151;
228  
229     // Push the new frame as the currently active one.
230     pushFrameStack( frame_d6f61ec0523939d4dfd5f12a04432151 );
231  
232     // Mark the frame object as in use, ref count 1 will be up for reuse.
233     assert( Py_REFCNT( frame_d6f61ec0523939d4dfd5f12a04432151 ) == 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_1 = "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_d6f61ec0523939d4dfd5f12a04432151 );
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_d6f61ec0523939d4dfd5f12a04432151 );
268 #endif
269  
270     if ( exception_tb == NULL )
271     {
272         exception_tb = MAKE_TRACEBACK( frame_d6f61ec0523939d4dfd5f12a04432151, exception_lineno );
273     }
274     else if ( exception_tb->tb_frame != &frame_d6f61ec0523939d4dfd5f12a04432151->m_frame )
275     {
276         exception_tb = ADD_TRACEBACK( exception_tb, frame_d6f61ec0523939d4dfd5f12a04432151, exception_lineno );
277     }
278  
279     // Attachs locals to frame if any.
280     Nuitka_Frame_AttachLocals(
281         (struct Nuitka_FrameObject *)frame_d6f61ec0523939d4dfd5f12a04432151,
282         type_description_1,
283         var_gen,
284         var_y
285     );
286  
287  
288     // Release cached frame.
289     if ( frame_d6f61ec0523939d4dfd5f12a04432151 == cache_frame_d6f61ec0523939d4dfd5f12a04432151 )
290     {
291         Py_DECREF( frame_d6f61ec0523939d4dfd5f12a04432151 );
292     }
293     cache_frame_d6f61ec0523939d4dfd5f12a04432151 = NULL;
294  
295     assertFrameObject( frame_d6f61ec0523939d4dfd5f12a04432151 );
296  
297     // Put the previous frame back on top.
298     popFrameStack();
299  
300     // Return the error.
301     goto try_except_handler_2;
302  
303     frame_no_exception_1:;
304  
305     tmp_return_value = PyTuple_New( 2 ); 219     tmp_return_value = PyTuple_New( 2 );
306     tmp_tuple_element_1 = var_y; 220     tmp_tuple_element_1 = var_y;
307 221
308     CHECK_OBJECT( tmp_tuple_element_1 ); 222     CHECK_OBJECT( tmp_tuple_element_1 );
309     Py_INCREF( tmp_tuple_element_1 ); 223     Py_INCREF( tmp_tuple_element_1 );
325 239
326     Py_XDECREF( var_y ); 240     Py_XDECREF( var_y );
327     var_y = NULL; 241     var_y = NULL;
328 242
329     goto function_return_exit; 243     goto function_return_exit;
n 330     // Exception handler code: n
331     try_except_handler_2:;
332     exception_keeper_type_1 = exception_type;
333     exception_keeper_value_1 = exception_value;
334     exception_keeper_tb_1 = exception_tb;
335     exception_keeper_lineno_1 = exception_lineno;
336     exception_type = NULL;
337     exception_value = NULL;
338     exception_tb = NULL;
339     exception_lineno = 0;
340  
341     CHECK_OBJECT( (PyObject *)var_gen );
342     Py_DECREF( var_gen );
343     var_gen = NULL;
344  
345     // Re-raise.
346     exception_type = exception_keeper_type_1;
347     exception_value = exception_keeper_value_1;
348     exception_tb = exception_keeper_tb_1;
349     exception_lineno = exception_keeper_lineno_1;
350  
351     goto function_exception_exit;
352     // End of try: 244     // End of try:
353 245
354     // Return statement must have exited already. 246     // Return statement must have exited already.
355     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 247     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
356     return NULL; 248     return NULL;
357 249
t 358 function_exception_exit: t
359     assert( exception_type );
360     RESTORE_ERROR_OCCURRED( exception_type, exception_value, exception_tb );
361  
362     return NULL;
363     function_return_exit: 250     function_return_exit:
364 251
365     CHECK_OBJECT( tmp_return_value ); 252     CHECK_OBJECT( tmp_return_value );
366     assert( had_error || !ERROR_OCCURRED() ); 253     assert( had_error || !ERROR_OCCURRED() );
367     return tmp_return_value; 254     return tmp_return_value;