Construct UnpackIterator

Performance Diagrams

Construct UnpackIterator 001000000100000020000002000000300000030000004000000400000050000005000000600000060000007000000700000080000008000000CPython 2.7Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)839862474.3076923076923257.0CPython 2.77900708198.15384615384616271.65034079941597Nuitka (historic)6213879322.0321.2824468581447Nuitka (master)6130499445.8461538461538323.73576311200134Nuitka (develop)6048503569.6923076923077326.1483574937624Nuitka (factory)Construct UnpackIteratorTicks Construct UnpackIterator 001000000100000020000002000000300000030000004000000400000050000005000000600000060000007000000700000080000008000000900000090000001000000010000000CPython 3.5Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)1004005973.61538461538461257.0CPython 3.50196.30769230769232504.11538461538464Nuitka (historic)6298659319.0000000000001349.0868592505283Nuitka (master)6350110441.69230769230774347.8204987984785Nuitka (develop)6353056564.3846153846155347.7479890728806Nuitka (factory)Construct UnpackIteratorTicks

Source Code with Construct

module_var = 1
range_arg = 2

def calledRepeatedly():
    global module_var
    c = module_var

    iterator=iter(range(range_arg))

# construct_begin
    a, b = iterator
# construct_alternative




    return a, b

for x in xrange(50000):
    calledRepeatedly()

print("OK.")

Source Code without Construct

module_var = 1
range_arg = 2

def calledRepeatedly():
    global module_var
    c = module_var

    iterator=iter(range(range_arg))

# construct_begin

# construct_alternative
    a = c
    b = c
# construct_end

    return a, b

for x in xrange(50000):
    calledRepeatedly()

print("OK.")

Context Diff of Source Code


Construct
Baseline
25     c = module_var 25     c = module_var
26 26
27     iterator=iter(range(range_arg)) 27     iterator=iter(range(range_arg))
28 28
29 # construct_begin 29 # construct_begin
n 30     a, b = iterator n 30  
31 # construct_alternative 31 # construct_alternative
t 32   t 32     a = c
33   33     b = c
34   34 # construct_end
35 35
36     return a, b 36     return a, b
37 37
38 for x in xrange(50000): 38 for x in xrange(50000):
39     calledRepeatedly() 39     calledRepeatedly()

Context Diff of Generated Code


Construct
Baseline
128     // Local variable declarations. 128     // Local variable declarations.
129     PyObject *var_c = NULL; 129     PyObject *var_c = NULL;
130     PyObject *var_iterator = NULL; 130     PyObject *var_iterator = NULL;
131     PyObject *var_a = NULL; 131     PyObject *var_a = NULL;
132     PyObject *var_b = NULL; 132     PyObject *var_b = NULL;
n 133     PyObject *tmp_tuple_unpack_1__source_iter = NULL; n
134     PyObject *tmp_tuple_unpack_1__element_1 = NULL;
135     PyObject *tmp_tuple_unpack_1__element_2 = NULL;
136     PyObject *exception_type = NULL, *exception_value = NULL; 133     PyObject *exception_type = NULL, *exception_value = NULL;
137     PyTracebackObject *exception_tb = NULL; 134     PyTracebackObject *exception_tb = NULL;
138     NUITKA_MAY_BE_UNUSED int exception_lineno = -1; 135     NUITKA_MAY_BE_UNUSED int exception_lineno = -1;
139     PyObject *exception_keeper_type_1; 136     PyObject *exception_keeper_type_1;
140     PyObject *exception_keeper_value_1; 137     PyObject *exception_keeper_value_1;
141     PyTracebackObject *exception_keeper_tb_1; 138     PyTracebackObject *exception_keeper_tb_1;
142     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 139     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
n 143     PyObject *exception_keeper_type_2; n
144     PyObject *exception_keeper_value_2;
145     PyTracebackObject *exception_keeper_tb_2;
146     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_2;
147     PyObject *exception_keeper_type_3;
148     PyObject *exception_keeper_value_3;
149     PyTracebackObject *exception_keeper_tb_3;
150     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
151     PyObject *tmp_assign_source_1; 140     PyObject *tmp_assign_source_1;
152     PyObject *tmp_assign_source_2; 141     PyObject *tmp_assign_source_2;
153     PyObject *tmp_assign_source_3; 142     PyObject *tmp_assign_source_3;
154     PyObject *tmp_assign_source_4; 143     PyObject *tmp_assign_source_4;
n 155     PyObject *tmp_assign_source_5; n
156     PyObject *tmp_assign_source_6;
157     PyObject *tmp_assign_source_7;
158     PyObject *tmp_iter_arg_1; 144     PyObject *tmp_iter_arg_1;
n 159     PyObject *tmp_iter_arg_2; n
160     PyObject *tmp_iterator_attempt;
161     PyObject *tmp_iterator_name_1;
162     PyObject *tmp_list_arg_1; 145     PyObject *tmp_list_arg_1;
163     PyObject *tmp_return_value; 146     PyObject *tmp_return_value;
164     PyObject *tmp_tuple_element_1; 147     PyObject *tmp_tuple_element_1;
n 165     PyObject *tmp_unpack_1; n
166     PyObject *tmp_unpack_2;
167     PyObject *tmp_xrange_low_1; 148     PyObject *tmp_xrange_low_1;
168     static struct Nuitka_FrameObject *cache_frame_859520bc69437d3d0a5095a9950f9aa0 = NULL; 149     static struct Nuitka_FrameObject *cache_frame_859520bc69437d3d0a5095a9950f9aa0 = NULL;
169 150
170     struct Nuitka_FrameObject *frame_859520bc69437d3d0a5095a9950f9aa0; 151     struct Nuitka_FrameObject *frame_859520bc69437d3d0a5095a9950f9aa0;
171 152
271         goto frame_exception_exit_1; 252         goto frame_exception_exit_1;
272     } 253     }
273     assert( var_iterator == NULL ); 254     assert( var_iterator == NULL );
274     var_iterator = tmp_assign_source_2; 255     var_iterator = tmp_assign_source_2;
275 256
n 276     // Tried code: n
277     tmp_iter_arg_2 = var_iterator;
278 257
n 279     CHECK_OBJECT( tmp_iter_arg_2 ); n 258 #if 0
280     tmp_assign_source_3 = MAKE_ITERATOR( tmp_iter_arg_2 ); 259     RESTORE_FRAME_EXCEPTION( frame_859520bc69437d3d0a5095a9950f9aa0 );
260 #endif
261  
262     // Put the previous frame back on top.
263     popFrameStack();
264  
265     goto frame_no_exception_1;
266  
267     frame_exception_exit_1:;
268  
269 #if 0
270     RESTORE_FRAME_EXCEPTION( frame_859520bc69437d3d0a5095a9950f9aa0 );
271 #endif
272  
273     if ( exception_tb == NULL )
274     {
275         exception_tb = MAKE_TRACEBACK( frame_859520bc69437d3d0a5095a9950f9aa0, exception_lineno );
276     }
277     else if ( exception_tb->tb_frame != &frame_859520bc69437d3d0a5095a9950f9aa0->m_frame )
278     {
279         exception_tb = ADD_TRACEBACK( exception_tb, frame_859520bc69437d3d0a5095a9950f9aa0, exception_lineno );
280     }
281  
282     Nuitka_Frame_AttachLocals( (struct Nuitka_FrameObject *)frame_859520bc69437d3d0a5095a9950f9aa0, type_description ,var_c, var_iterator, var_a, var_b );
283  
284     // Release cached frame.
285     if ( frame_859520bc69437d3d0a5095a9950f9aa0 == cache_frame_859520bc69437d3d0a5095a9950f9aa0 )
286     {
287         Py_DECREF( frame_859520bc69437d3d0a5095a9950f9aa0 );
288     }
289     cache_frame_859520bc69437d3d0a5095a9950f9aa0 = NULL;
290  
291     assertFrameObject( frame_859520bc69437d3d0a5095a9950f9aa0 );
292  
293  
294     // Put the previous frame back on top.
295     popFrameStack();
296  
297     // Return the error.
298     goto try_except_handler_1;
299  
300     frame_no_exception_1:;
301  
302     tmp_assign_source_3 = var_c;
303  
281     if ( tmp_assign_source_3 == NULL ) 304     if ( tmp_assign_source_3 == NULL )
282     { 305     {
n 283         assert( ERROR_OCCURRED() ); n
284 306
n n 307         exception_type = PyExc_UnboundLocalError;
308         Py_INCREF( exception_type );
309         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "c" );
310         exception_tb = NULL;
285         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb ); 311         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
312         CHAIN_EXCEPTION( exception_value );
286 313
287 314
n 288         exception_lineno = 30; n 315  
289         type_description = "oooo";
290         goto try_except_handler_2; 316         goto try_except_handler_1;
291     } 317     }
n 292     assert( tmp_tuple_unpack_1__source_iter == NULL ); n
293     tmp_tuple_unpack_1__source_iter = tmp_assign_source_3;
294 318
n 295     // Tried code: n 319     assert( var_a == NULL );
296     tmp_unpack_1 = tmp_tuple_unpack_1__source_iter; 320     Py_INCREF( tmp_assign_source_3 );
321     var_a = tmp_assign_source_3;
297 322
n 298     CHECK_OBJECT( tmp_unpack_1 ); n 323     tmp_assign_source_4 = var_c;
299     tmp_assign_source_4 = UNPACK_NEXT( tmp_unpack_1, 0, 2 ); 324  
300     if ( tmp_assign_source_4 == NULL ) 325     if ( tmp_assign_source_4 == NULL )
301     { 326     {
n 302         if ( !ERROR_OCCURRED() ) n 327  
303         { 328         exception_type = PyExc_UnboundLocalError;
304             exception_type = PyExc_StopIteration;
305             Py_INCREF( exception_type ); 329         Py_INCREF( exception_type );
306             exception_value = NULL; 330         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "c" );
307             exception_tb = NULL; 331         exception_tb = NULL;
308         }
309         else
310         {
311             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb ); 332         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
312         } 333         CHAIN_EXCEPTION( exception_value );
313 334
314 335
n 315         type_description = "oooo"; n 336  
316         exception_lineno = 30;
317         goto try_except_handler_3; 337         goto try_except_handler_1;
318     }
319     assert( tmp_tuple_unpack_1__element_1 == NULL );
320     tmp_tuple_unpack_1__element_1 = tmp_assign_source_4;
321  
322     tmp_unpack_2 = tmp_tuple_unpack_1__source_iter;
323  
324     CHECK_OBJECT( tmp_unpack_2 );
325     tmp_assign_source_5 = UNPACK_NEXT( tmp_unpack_2, 1, 2 );
326     if ( tmp_assign_source_5 == NULL )
327     { 338     }
328         if ( !ERROR_OCCURRED() )
329         {
330             exception_type = PyExc_StopIteration;
331             Py_INCREF( exception_type );
332             exception_value = NULL;
333             exception_tb = NULL;
334         }
335         else
336         {
337             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
338         }
339 339
n n 340     assert( var_b == NULL );
341     Py_INCREF( tmp_assign_source_4 );
342     var_b = tmp_assign_source_4;
340 343
n 341         type_description = "oooo"; n 344     tmp_return_value = PyTuple_New( 2 );
342         exception_lineno = 30; 345     tmp_tuple_element_1 = var_a;
343         goto try_except_handler_3;
344     }
345     assert( tmp_tuple_unpack_1__element_2 == NULL );
346     tmp_tuple_unpack_1__element_2 = tmp_assign_source_5;
347 346
n 348     tmp_iterator_name_1 = tmp_tuple_unpack_1__source_iter; n
349  
350     CHECK_OBJECT( tmp_iterator_name_1 ); 347     CHECK_OBJECT( tmp_tuple_element_1 );
351     // Check if iterator has left-over elements. 348     Py_INCREF( tmp_tuple_element_1 );
352     CHECK_OBJECT( tmp_iterator_name_1 ); assert( HAS_ITERNEXT( tmp_iterator_name_1 ) ); 349     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
350     tmp_tuple_element_1 = var_b;
353 351
n 354     tmp_iterator_attempt = (*Py_TYPE( tmp_iterator_name_1 )->tp_iternext)( tmp_iterator_name_1 ); n 352     CHECK_OBJECT( tmp_tuple_element_1 );
355   353     Py_INCREF( tmp_tuple_element_1 );
356     if (likely( tmp_iterator_attempt == NULL )) 354     PyTuple_SET_ITEM( tmp_return_value, 1, tmp_tuple_element_1 );
357     {
358         PyObject *error = GET_ERROR_OCCURRED();
359  
360         if ( error != NULL )
361         {
362             if ( EXCEPTION_MATCH_BOOL_SINGLE( error, PyExc_StopIteration ))
363             {
364                 CLEAR_ERROR_OCCURRED();
365             }
366             else
367             {
368                 FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
369  
370                 type_description = "oooo";
371                 goto try_except_handler_3;
372             }
373         }
374     }
375     else
376     {
377         Py_DECREF( tmp_iterator_attempt );
378  
379         // TODO: Could avoid PyErr_Format.
380 #if PYTHON_VERSION < 300
381         PyErr_Format( PyExc_ValueError, "too many values to unpack" );
382 #else
383         PyErr_Format( PyExc_ValueError, "too many values to unpack (expected 2)" );
384 #endif
385         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
386  
387         type_description = "oooo";
388         goto try_except_handler_3; 355     goto try_return_handler_1;
389     } 356     // tried codes exits in all cases
390     goto try_end_1; 357     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
358     return NULL;
359     // Return handler code:
360     try_return_handler_1:;
361     Py_XDECREF( var_c );
362     var_c = NULL;
363  
364     Py_XDECREF( var_iterator );
365     var_iterator = NULL;
366  
367     Py_XDECREF( var_a );
368     var_a = NULL;
369  
370     Py_XDECREF( var_b );
371     var_b = NULL;
372  
373     goto function_return_exit;
391     // Exception handler code: 374     // Exception handler code:
n 392     try_except_handler_3:; n 375     try_except_handler_1:;
393     exception_keeper_type_1 = exception_type; 376     exception_keeper_type_1 = exception_type;
394     exception_keeper_value_1 = exception_value; 377     exception_keeper_value_1 = exception_value;
395     exception_keeper_tb_1 = exception_tb; 378     exception_keeper_tb_1 = exception_tb;
396     exception_keeper_lineno_1 = exception_lineno; 379     exception_keeper_lineno_1 = exception_lineno;
397     exception_type = NULL; 380     exception_type = NULL;
398     exception_value = NULL; 381     exception_value = NULL;
399     exception_tb = NULL; 382     exception_tb = NULL;
400     exception_lineno = -1; 383     exception_lineno = -1;
401 384
n 402     Py_XDECREF( tmp_tuple_unpack_1__source_iter ); n 385     Py_XDECREF( var_c );
403     tmp_tuple_unpack_1__source_iter = NULL; 386     var_c = NULL;
404 387
405     // Re-raise. 388     // Re-raise.
406     exception_type = exception_keeper_type_1; 389     exception_type = exception_keeper_type_1;
407     exception_value = exception_keeper_value_1; 390     exception_value = exception_keeper_value_1;
408     exception_tb = exception_keeper_tb_1; 391     exception_tb = exception_keeper_tb_1;
409     exception_lineno = exception_keeper_lineno_1; 392     exception_lineno = exception_keeper_lineno_1;
t 410   t
411     goto try_except_handler_2;
412     // End of try:
413     try_end_1:;
414     goto try_end_2;
415     // Exception handler code:
416     try_except_handler_2:;
417     exception_keeper_type_2 = exception_type;
418     exception_keeper_value_2 = exception_value;
419     exception_keeper_tb_2 = exception_tb;
420     exception_keeper_lineno_2 = exception_lineno;
421     exception_type = NULL;
422     exception_value = NULL;
423     exception_tb = NULL;
424     exception_lineno = -1;
425  
426     Py_XDECREF( tmp_tuple_unpack_1__element_1 );
427     tmp_tuple_unpack_1__element_1 = NULL;
428  
429     Py_XDECREF( tmp_tuple_unpack_1__element_2 );
430     tmp_tuple_unpack_1__element_2 = NULL;
431  
432     // Re-raise.
433     exception_type = exception_keeper_type_2;
434     exception_value = exception_keeper_value_2;
435     exception_tb = exception_keeper_tb_2;
436     exception_lineno = exception_keeper_lineno_2;
437  
438     goto frame_exception_exit_1;
439     // End of try:
440     try_end_2:;
441     Py_XDECREF( tmp_tuple_unpack_1__source_iter );
442     tmp_tuple_unpack_1__source_iter = NULL;
443  
444     tmp_assign_source_6 = tmp_tuple_unpack_1__element_1;
445  
446     CHECK_OBJECT( tmp_assign_source_6 );
447     assert( var_a == NULL );
448     Py_INCREF( tmp_assign_source_6 );
449     var_a = tmp_assign_source_6;
450  
451     Py_XDECREF( tmp_tuple_unpack_1__element_1 );
452     tmp_tuple_unpack_1__element_1 = NULL;
453  
454     tmp_assign_source_7 = tmp_tuple_unpack_1__element_2;
455  
456     CHECK_OBJECT( tmp_assign_source_7 );
457     assert( var_b == NULL );
458     Py_INCREF( tmp_assign_source_7 );
459     var_b = tmp_assign_source_7;
460  
461     Py_XDECREF( tmp_tuple_unpack_1__element_2 );
462     tmp_tuple_unpack_1__element_2 = NULL;
463  
464     Py_XDECREF( tmp_tuple_unpack_1__element_1 );
465     tmp_tuple_unpack_1__element_1 = NULL;
466  
467     Py_XDECREF( tmp_tuple_unpack_1__element_2 );
468     tmp_tuple_unpack_1__element_2 = NULL;
469  
470     tmp_return_value = PyTuple_New( 2 );
471     tmp_tuple_element_1 = var_a;
472  
473     if ( tmp_tuple_element_1 == NULL )
474     {
475         Py_DECREF( tmp_return_value );
476         exception_type = PyExc_UnboundLocalError;
477         Py_INCREF( exception_type );
478         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "a" );
479         exception_tb = NULL;
480         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
481         CHAIN_EXCEPTION( exception_value );
482  
483         exception_lineno = 36;
484         type_description = "oooo";
485         goto frame_exception_exit_1;
486     }
487  
488     Py_INCREF( tmp_tuple_element_1 );
489     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
490     tmp_tuple_element_1 = var_b;
491  
492     if ( tmp_tuple_element_1 == NULL )
493     {
494         Py_DECREF( tmp_return_value );
495         exception_type = PyExc_UnboundLocalError;
496         Py_INCREF( exception_type );
497         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "b" );
498         exception_tb = NULL;
499         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
500         CHAIN_EXCEPTION( exception_value );
501  
502         exception_lineno = 36;
503         type_description = "oooo";
504         goto frame_exception_exit_1;
505     }
506  
507     Py_INCREF( tmp_tuple_element_1 );
508     PyTuple_SET_ITEM( tmp_return_value, 1, tmp_tuple_element_1 );
509     goto frame_return_exit_1;
510  
511 #if 0
512     RESTORE_FRAME_EXCEPTION( frame_859520bc69437d3d0a5095a9950f9aa0 );
513 #endif
514  
515     // Put the previous frame back on top.
516     popFrameStack();
517  
518     goto frame_no_exception_1;
519  
520     frame_return_exit_1:;
521 #if 0
522     RESTORE_FRAME_EXCEPTION( frame_859520bc69437d3d0a5095a9950f9aa0 );
523 #endif
524  
525     // Put the previous frame back on top.
526     popFrameStack();
527  
528     goto try_return_handler_1;
529  
530     frame_exception_exit_1:;
531  
532 #if 0
533     RESTORE_FRAME_EXCEPTION( frame_859520bc69437d3d0a5095a9950f9aa0 );
534 #endif
535  
536     if ( exception_tb == NULL )
537     {
538         exception_tb = MAKE_TRACEBACK( frame_859520bc69437d3d0a5095a9950f9aa0, exception_lineno );
539     }
540     else if ( exception_tb->tb_frame != &frame_859520bc69437d3d0a5095a9950f9aa0->m_frame )
541     {
542         exception_tb = ADD_TRACEBACK( exception_tb, frame_859520bc69437d3d0a5095a9950f9aa0, exception_lineno );
543     }
544  
545     Nuitka_Frame_AttachLocals( (struct Nuitka_FrameObject *)frame_859520bc69437d3d0a5095a9950f9aa0, type_description ,var_c, var_iterator, var_a, var_b );
546  
547     // Release cached frame.
548     if ( frame_859520bc69437d3d0a5095a9950f9aa0 == cache_frame_859520bc69437d3d0a5095a9950f9aa0 )
549     {
550         Py_DECREF( frame_859520bc69437d3d0a5095a9950f9aa0 );
551     }
552     cache_frame_859520bc69437d3d0a5095a9950f9aa0 = NULL;
553  
554     assertFrameObject( frame_859520bc69437d3d0a5095a9950f9aa0 );
555  
556  
557     // Put the previous frame back on top.
558     popFrameStack();
559  
560     // Return the error.
561     goto try_except_handler_1;
562  
563     frame_no_exception_1:;
564  
565     // tried codes exits in all cases
566     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
567     return NULL;
568     // Return handler code:
569     try_return_handler_1:;
570     Py_XDECREF( var_c );
571     var_c = NULL;
572  
573     Py_XDECREF( var_iterator );
574     var_iterator = NULL;
575  
576     Py_XDECREF( var_a );
577     var_a = NULL;
578  
579     Py_XDECREF( var_b );
580     var_b = NULL;
581  
582     goto function_return_exit;
583     // Exception handler code:
584     try_except_handler_1:;
585     exception_keeper_type_3 = exception_type;
586     exception_keeper_value_3 = exception_value;
587     exception_keeper_tb_3 = exception_tb;
588     exception_keeper_lineno_3 = exception_lineno;
589     exception_type = NULL;
590     exception_value = NULL;
591     exception_tb = NULL;
592     exception_lineno = -1;
593  
594     Py_XDECREF( var_c );
595     var_c = NULL;
596  
597     Py_XDECREF( var_iterator );
598     var_iterator = NULL;
599  
600     Py_XDECREF( var_a );
601     var_a = NULL;
602  
603     Py_XDECREF( var_b );
604     var_b = NULL;
605  
606     // Re-raise.
607     exception_type = exception_keeper_type_3;
608     exception_value = exception_keeper_value_3;
609     exception_tb = exception_keeper_tb_3;
610     exception_lineno = exception_keeper_lineno_3;
611 393
612     goto function_exception_exit; 394     goto function_exception_exit;
613     // End of try: 395     // End of try:
614 396
615     // Return statement must have exited already. 397     // Return statement must have exited already.