Construct UnpackIterator

Performance Diagrams

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