Construct BuiltinSumWithGenerator

Performance Diagrams

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