Construct BuiltinSumWithGenerator

Performance Diagrams

Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)22311586888.11538461538461257.0CPython 2.7121826135240.03846153846155369.18498958525277Nuitka (master)121826291391.96153846153845369.184816805072Nuitka (develop)121826171543.8846153846154369.1849497129033Nuitka (factory)Construct BuiltinSumWithGeneratorTicks Construct BuiltinSumWithGenerator 0040000000400000008000000080000000120000000120000000160000000160000000200000000200000000240000000240000000280000000280000000320000000320000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)32286353988.11538461538461257.0CPython 3.5172804409240.03846153846155371.85322789886163Nuitka (master)172804255391.96153846153845371.85334576837806Nuitka (develop)172815347543.8846153846154371.8448561016457Nuitka (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
145 145
146     // Local variable declarations. 146     // Local variable declarations.
147     PyObject *var_y = NULL; 147     PyObject *var_y = NULL;
148     PyObject *var_gen = NULL; 148     PyObject *var_gen = NULL;
149     PyObject *tmp_genexpr_1__$0 = NULL; 149     PyObject *tmp_genexpr_1__$0 = NULL;
n 150     struct Nuitka_FrameObject *frame_806b29086f0b76056a46db0c818e5b90; n
151     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
152     PyObject *exception_type = NULL;
153     PyObject *exception_value = NULL;
154     PyTracebackObject *exception_tb = NULL;
155     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
156     static struct Nuitka_FrameObject *cache_frame_806b29086f0b76056a46db0c818e5b90 = NULL;
157     PyObject *tmp_return_value = NULL; 150     PyObject *tmp_return_value = NULL;
n 158     PyObject *exception_keeper_type_1; n
159     PyObject *exception_keeper_value_1;
160     PyTracebackObject *exception_keeper_tb_1;
161     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
162 151
163     // Actual function code. 152     // Actual function code.
164     { 153     {
165     PyObject *tmp_assign_source_1; 154     PyObject *tmp_assign_source_1;
166     { 155     {
212     assert( var_gen == NULL ); 201     assert( var_gen == NULL );
213     var_gen = tmp_assign_source_1; 202     var_gen = tmp_assign_source_1;
214 203
215     } 204     }
216     { 205     {
n n 206     PyObject *tmp_assign_source_3;
207     CHECK_OBJECT( var_gen );
208     tmp_assign_source_3 = var_gen;
209     assert( var_y == NULL );
210     Py_INCREF( tmp_assign_source_3 );
211     var_y = tmp_assign_source_3;
212  
213     }
214     {
217     // Tried code: 215     // Tried code:
n 218     MAKE_OR_REUSE_FRAME( cache_frame_806b29086f0b76056a46db0c818e5b90, codeobj_806b29086f0b76056a46db0c818e5b90, module___main__, sizeof(void *)+sizeof(void *) ); n
219     frame_806b29086f0b76056a46db0c818e5b90 = cache_frame_806b29086f0b76056a46db0c818e5b90;
220  
221     // Push the new frame as the currently active one.
222     pushFrameStack( frame_806b29086f0b76056a46db0c818e5b90 );
223  
224     // Mark the frame object as in use, ref count 1 will be up for reuse.
225     assert( Py_REFCNT( frame_806b29086f0b76056a46db0c818e5b90 ) == 2 ); // Frame stack
226  
227     // Framed code:
228     {
229     PyObject *tmp_assign_source_3;
230     PyObject *tmp_sum_sequence_1;
231     CHECK_OBJECT( var_gen );
232     tmp_sum_sequence_1 = var_gen;
233     tmp_assign_source_3 = BUILTIN_SUM1( tmp_sum_sequence_1 );
234     if ( tmp_assign_source_3 == NULL )
235     {
236         assert( ERROR_OCCURRED() );
237  
238         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
239  
240  
241         exception_lineno = 29;
242         type_description_1 = "oo";
243         goto frame_exception_exit_1;
244     }
245     assert( var_y == NULL );
246     var_y = tmp_assign_source_3;
247  
248     }
249  
250 #if 0
251     RESTORE_FRAME_EXCEPTION( frame_806b29086f0b76056a46db0c818e5b90 );
252 #endif
253  
254     // Put the previous frame back on top.
255     popFrameStack();
256  
257     goto frame_no_exception_1;
258  
259     frame_exception_exit_1:;
260  
261 #if 0
262     RESTORE_FRAME_EXCEPTION( frame_806b29086f0b76056a46db0c818e5b90 );
263 #endif
264  
265     if ( exception_tb == NULL )
266     {
267         exception_tb = MAKE_TRACEBACK( frame_806b29086f0b76056a46db0c818e5b90, exception_lineno );
268     }
269     else if ( exception_tb->tb_frame != &frame_806b29086f0b76056a46db0c818e5b90->m_frame )
270     {
271         exception_tb = ADD_TRACEBACK( exception_tb, frame_806b29086f0b76056a46db0c818e5b90, exception_lineno );
272     }
273  
274     // Attachs locals to frame if any.
275     Nuitka_Frame_AttachLocals(
276         (struct Nuitka_FrameObject *)frame_806b29086f0b76056a46db0c818e5b90,
277         type_description_1,
278         var_y,
279         var_gen
280     );
281  
282  
283     // Release cached frame.
284     if ( frame_806b29086f0b76056a46db0c818e5b90 == cache_frame_806b29086f0b76056a46db0c818e5b90 )
285     {
286         Py_DECREF( frame_806b29086f0b76056a46db0c818e5b90 );
287     }
288     cache_frame_806b29086f0b76056a46db0c818e5b90 = NULL;
289  
290     assertFrameObject( frame_806b29086f0b76056a46db0c818e5b90 );
291  
292     // Put the previous frame back on top.
293     popFrameStack();
294  
295     // Return the error.
296     goto try_except_handler_2;
297  
298     frame_no_exception_1:;
299     { 216     {
300     PyObject *tmp_tuple_element_1; 217     PyObject *tmp_tuple_element_1;
301     CHECK_OBJECT( var_y ); 218     CHECK_OBJECT( var_y );
302     tmp_tuple_element_1 = var_y; 219     tmp_tuple_element_1 = var_y;
303     tmp_return_value = PyTuple_New( 2 ); 220     tmp_return_value = PyTuple_New( 2 );
326 243
327     } 244     }
328     { 245     {
329     goto function_return_exit; 246     goto function_return_exit;
330     } 247     }
n 331     // Exception handler code: n
332     try_except_handler_2:;
333     exception_keeper_type_1 = exception_type;
334     exception_keeper_value_1 = exception_value;
335     exception_keeper_tb_1 = exception_tb;
336     exception_keeper_lineno_1 = exception_lineno;
337     exception_type = NULL;
338     exception_value = NULL;
339     exception_tb = NULL;
340     exception_lineno = 0;
341  
342     {
343     CHECK_OBJECT( (PyObject *)var_gen );
344     Py_DECREF( var_gen );
345     var_gen = NULL;
346  
347     }
348     {
349     // Re-raise.
350     exception_type = exception_keeper_type_1;
351     exception_value = exception_keeper_value_1;
352     exception_tb = exception_keeper_tb_1;
353     exception_lineno = exception_keeper_lineno_1;
354  
355     goto function_exception_exit;
356     }
357     // End of try: 248     // End of try:
358     } 249     }
359 250
360     // Return statement must have exited already. 251     // Return statement must have exited already.
361     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 252     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
362     return NULL; 253     return NULL;
363 254
t 364 function_exception_exit: t
365     assert( exception_type );
366     RESTORE_ERROR_OCCURRED( exception_type, exception_value, exception_tb );
367  
368     return NULL;
369 function_return_exit: 255 function_return_exit:
370 256
371 CHECK_OBJECT( tmp_return_value ); 257 CHECK_OBJECT( tmp_return_value );
372 assert( had_error || !ERROR_OCCURRED() ); 258 assert( had_error || !ERROR_OCCURRED() );
373 return tmp_return_value; 259 return tmp_return_value;