Construct BuiltinSumWithGenerator

Performance Diagrams

Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000CPython 2.7Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)19085305072.9230769230769297.5417148401322CPython 2.70194.46153846153845504.11538461538464Nuitka (historic)228309469316.0257.0Nuitka (master)227308362437.53846153846143258.08356846708864Nuitka (develop)227309169559.0769230769231258.0826949942701Nuitka (factory)Construct BuiltinSumWithGeneratorTicks Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000280000000280000000300000000300000000CPython 3.5Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)30373519072.9230769230769257.0CPython 3.50194.46153846153845504.11538461538464Nuitka (historic)271554323316.0283.1819755753739Nuitka (master)270542654437.53846153846143284.0050575963885Nuitka (develop)270544008559.0769230769231284.003955997885Nuitka (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

for x in xrange(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

for x in xrange(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 for x in xrange(500): 36 for x in xrange(500):
37     calledRepeatedly() 37     calledRepeatedly()

Context Diff of Generated Code


Construct
Baseline
136 136
137     // Local variable declarations. 137     // Local variable declarations.
138     PyObject *var_gen = NULL; 138     PyObject *var_gen = NULL;
139     PyObject *var_y = NULL; 139     PyObject *var_y = NULL;
140     PyObject *tmp_genexpr_1__$0 = NULL; 140     PyObject *tmp_genexpr_1__$0 = NULL;
n 141     PyObject *exception_type = NULL, *exception_value = NULL; n
142     PyTracebackObject *exception_tb = NULL;
143     NUITKA_MAY_BE_UNUSED int exception_lineno = -1;
144     PyObject *exception_keeper_type_1;
145     PyObject *exception_keeper_value_1;
146     PyTracebackObject *exception_keeper_tb_1;
147     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
148     PyObject *tmp_assign_source_1; 141     PyObject *tmp_assign_source_1;
149     PyObject *tmp_assign_source_2; 142     PyObject *tmp_assign_source_2;
150     PyObject *tmp_assign_source_3; 143     PyObject *tmp_assign_source_3;
151     PyObject *tmp_iter_arg_1; 144     PyObject *tmp_iter_arg_1;
152     PyObject *tmp_outline_return_value_1; 145     PyObject *tmp_outline_return_value_1;
153     PyObject *tmp_return_value; 146     PyObject *tmp_return_value;
n 154     PyObject *tmp_sum_sequence_1; n
155     PyObject *tmp_tuple_element_1; 147     PyObject *tmp_tuple_element_1;
n 156     static struct Nuitka_FrameObject *cache_frame_8e4d3822ca0c32cb5af7be221e8200c8 = NULL; n
157  
158     struct Nuitka_FrameObject *frame_8e4d3822ca0c32cb5af7be221e8200c8;
159  
160     char const *type_description;
161     tmp_return_value = NULL; 148     tmp_return_value = NULL;
162     tmp_outline_return_value_1 = NULL; 149     tmp_outline_return_value_1 = NULL;
163 150
164     // Actual function code. 151     // Actual function code.
165     tmp_iter_arg_1 = const_xrange_0_1000; 152     tmp_iter_arg_1 = const_xrange_0_1000;
206     outline_result_1:; 193     outline_result_1:;
207     tmp_assign_source_1 = tmp_outline_return_value_1; 194     tmp_assign_source_1 = tmp_outline_return_value_1;
208     assert( var_gen == NULL ); 195     assert( var_gen == NULL );
209     var_gen = tmp_assign_source_1; 196     var_gen = tmp_assign_source_1;
210 197
n n 198     tmp_assign_source_3 = var_gen;
199  
200     CHECK_OBJECT( tmp_assign_source_3 );
201     assert( var_y == NULL );
202     Py_INCREF( tmp_assign_source_3 );
203     var_y = tmp_assign_source_3;
204  
211     // Tried code: 205     // Tried code:
n 212     MAKE_OR_REUSE_FRAME( cache_frame_8e4d3822ca0c32cb5af7be221e8200c8, codeobj_8e4d3822ca0c32cb5af7be221e8200c8, module___main__, sizeof(PyObject *)+sizeof(PyObject *) ); n
213     frame_8e4d3822ca0c32cb5af7be221e8200c8 = cache_frame_8e4d3822ca0c32cb5af7be221e8200c8;
214  
215     // Push the new frame as the currently active one.
216     pushFrameStack( frame_8e4d3822ca0c32cb5af7be221e8200c8 );
217  
218     // Mark the frame object as in use, ref count 1 will be up for reuse.
219     assert( Py_REFCNT( frame_8e4d3822ca0c32cb5af7be221e8200c8 ) == 2 ); // Frame stack
220  
221     // Framed code:
222     tmp_sum_sequence_1 = var_gen;
223  
224     CHECK_OBJECT( tmp_sum_sequence_1 );
225     tmp_assign_source_3 = BUILTIN_SUM1( tmp_sum_sequence_1 );
226     if ( tmp_assign_source_3 == NULL )
227     {
228         assert( ERROR_OCCURRED() );
229  
230         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
231  
232  
233         exception_lineno = 29;
234         type_description = "oo";
235         goto frame_exception_exit_1;
236     }
237     assert( var_y == NULL );
238     var_y = tmp_assign_source_3;
239  
240  
241 #if 0
242     RESTORE_FRAME_EXCEPTION( frame_8e4d3822ca0c32cb5af7be221e8200c8 );
243 #endif
244  
245     // Put the previous frame back on top.
246     popFrameStack();
247  
248     goto frame_no_exception_1;
249  
250     frame_exception_exit_1:;
251  
252 #if 0
253     RESTORE_FRAME_EXCEPTION( frame_8e4d3822ca0c32cb5af7be221e8200c8 );
254 #endif
255  
256     if ( exception_tb == NULL )
257     {
258         exception_tb = MAKE_TRACEBACK( frame_8e4d3822ca0c32cb5af7be221e8200c8, exception_lineno );
259     }
260     else if ( exception_tb->tb_frame != &frame_8e4d3822ca0c32cb5af7be221e8200c8->m_frame )
261     {
262         exception_tb = ADD_TRACEBACK( exception_tb, frame_8e4d3822ca0c32cb5af7be221e8200c8, exception_lineno );
263     }
264  
265     Nuitka_Frame_AttachLocals( (struct Nuitka_FrameObject *)frame_8e4d3822ca0c32cb5af7be221e8200c8, type_description ,var_gen, var_y );
266  
267     // Release cached frame.
268     if ( frame_8e4d3822ca0c32cb5af7be221e8200c8 == cache_frame_8e4d3822ca0c32cb5af7be221e8200c8 )
269     {
270         Py_DECREF( frame_8e4d3822ca0c32cb5af7be221e8200c8 );
271     }
272     cache_frame_8e4d3822ca0c32cb5af7be221e8200c8 = NULL;
273  
274     assertFrameObject( frame_8e4d3822ca0c32cb5af7be221e8200c8 );
275  
276  
277     // Put the previous frame back on top.
278     popFrameStack();
279  
280     // Return the error.
281     goto try_except_handler_2;
282  
283     frame_no_exception_1:;
284  
285     tmp_return_value = PyTuple_New( 2 ); 206     tmp_return_value = PyTuple_New( 2 );
286     tmp_tuple_element_1 = var_y; 207     tmp_tuple_element_1 = var_y;
287 208
288     CHECK_OBJECT( tmp_tuple_element_1 ); 209     CHECK_OBJECT( tmp_tuple_element_1 );
289     Py_INCREF( tmp_tuple_element_1 ); 210     Py_INCREF( tmp_tuple_element_1 );
305 226
306     Py_XDECREF( var_y ); 227     Py_XDECREF( var_y );
307     var_y = NULL; 228     var_y = NULL;
308 229
309     goto function_return_exit; 230     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 = -1;
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: 231     // End of try:
333 232
334     // Return statement must have exited already. 233     // Return statement must have exited already.
335     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 234     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
336     return NULL; 235     return NULL;
337 236
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     function_return_exit: 237     function_return_exit:
344 238
345     CHECK_OBJECT( tmp_return_value ); 239     CHECK_OBJECT( tmp_return_value );
346     assert( had_error || !ERROR_OCCURRED() ); 240     assert( had_error || !ERROR_OCCURRED() );
347     return tmp_return_value; 241     return tmp_return_value;