Construct BuiltinSumWithGenerator

Performance Diagrams

Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)22311586888.11538461538461257.0CPython 2.7121833449240.03846153846155369.17688885293245Nuitka (master)121826423391.96153846153845369.18467060645753Nuitka (develop)121826417543.8846153846154369.18467725184905Nuitka (factory)Construct BuiltinSumWithGeneratorTicks Construct BuiltinSumWithGenerator 0040000000400000008000000080000000120000000120000000160000000160000000200000000200000000240000000240000000280000000280000000320000000320000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)32286353988.11538461538461257.0CPython 3.5172799397240.03846153846155371.85706401585253Nuitka (master)172804069391.96153846153845371.85348813026167Nuitka (develop)172804099543.8846153846154371.8534651686675Nuitka (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_b99a1d952e7527772869cf4903b780ba; 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_b99a1d952e7527772869cf4903b780ba = 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_b99a1d952e7527772869cf4903b780ba, codeobj_b99a1d952e7527772869cf4903b780ba, module___main__, sizeof(void *)+sizeof(void *) ); n
219     frame_b99a1d952e7527772869cf4903b780ba = cache_frame_b99a1d952e7527772869cf4903b780ba;
220  
221     // Push the new frame as the currently active one.
222     pushFrameStack( frame_b99a1d952e7527772869cf4903b780ba );
223  
224     // Mark the frame object as in use, ref count 1 will be up for reuse.
225     assert( Py_REFCNT( frame_b99a1d952e7527772869cf4903b780ba ) == 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_b99a1d952e7527772869cf4903b780ba );
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_b99a1d952e7527772869cf4903b780ba );
263 #endif
264  
265     if ( exception_tb == NULL )
266     {
267         exception_tb = MAKE_TRACEBACK( frame_b99a1d952e7527772869cf4903b780ba, exception_lineno );
268     }
269     else if ( exception_tb->tb_frame != &frame_b99a1d952e7527772869cf4903b780ba->m_frame )
270     {
271         exception_tb = ADD_TRACEBACK( exception_tb, frame_b99a1d952e7527772869cf4903b780ba, exception_lineno );
272     }
273  
274     // Attachs locals to frame if any.
275     Nuitka_Frame_AttachLocals(
276         (struct Nuitka_FrameObject *)frame_b99a1d952e7527772869cf4903b780ba,
277         type_description_1,
278         var_y,
279         var_gen
280     );
281  
282  
283     // Release cached frame.
284     if ( frame_b99a1d952e7527772869cf4903b780ba == cache_frame_b99a1d952e7527772869cf4903b780ba )
285     {
286         Py_DECREF( frame_b99a1d952e7527772869cf4903b780ba );
287     }
288     cache_frame_b99a1d952e7527772869cf4903b780ba = NULL;
289  
290     assertFrameObject( frame_b99a1d952e7527772869cf4903b780ba );
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 );
327 244
328     } 245     }
329     { 246     {
330     goto function_return_exit; 247     goto function_return_exit;
331     } 248     }
n 332     // Exception handler code: n
333     try_except_handler_2:;
334     exception_keeper_type_1 = exception_type;
335     exception_keeper_value_1 = exception_value;
336     exception_keeper_tb_1 = exception_tb;
337     exception_keeper_lineno_1 = exception_lineno;
338     exception_type = NULL;
339     exception_value = NULL;
340     exception_tb = NULL;
341     exception_lineno = 0;
342  
343     {
344     CHECK_OBJECT( (PyObject *)var_gen );
345     Py_DECREF( var_gen );
346     var_gen = NULL;
347  
348     }
349     {
350     // Re-raise.
351     exception_type = exception_keeper_type_1;
352     exception_value = exception_keeper_value_1;
353     exception_tb = exception_keeper_tb_1;
354     exception_lineno = exception_keeper_lineno_1;
355  
356     goto function_exception_exit;
357     }
358     // End of try: 249     // End of try:
359     } 250     }
360 251
361     // Return statement must have exited already. 252     // Return statement must have exited already.
362     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 253     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
363     return NULL; 254     return NULL;
364 255
t 365 function_exception_exit: t
366     assert( exception_type );
367     RESTORE_ERROR_OCCURRED( exception_type, exception_value, exception_tb );
368  
369     return NULL;
370 function_return_exit: 256 function_return_exit:
371 257
372 CHECK_OBJECT( tmp_return_value ); 258 CHECK_OBJECT( tmp_return_value );
373 assert( had_error || !ERROR_OCCURRED() ); 259 assert( had_error || !ERROR_OCCURRED() );
374 return tmp_return_value; 260 return tmp_return_value;