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)6100033445.8461538461538324.6321739178301Nuitka (develop)6102037569.6923076923077324.5732095885817Nuitka (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)6252020441.69230769230774350.2347822281798Nuitka (develop)6248987564.3846153846155350.30943327968646Nuitka (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_frame_locals; 145     PyObject *tmp_frame_locals;
160     PyObject *tmp_iter_arg_1; 146     PyObject *tmp_iter_arg_1;
n 161     PyObject *tmp_iter_arg_2; n
162     PyObject *tmp_iterator_attempt;
163     PyObject *tmp_iterator_name_1;
164     PyObject *tmp_list_arg_1; 147     PyObject *tmp_list_arg_1;
165     PyObject *tmp_return_value; 148     PyObject *tmp_return_value;
166     PyObject *tmp_tuple_element_1; 149     PyObject *tmp_tuple_element_1;
n 167     PyObject *tmp_unpack_1; n
168     PyObject *tmp_unpack_2;
169     PyObject *tmp_xrange_low_1; 150     PyObject *tmp_xrange_low_1;
170     static PyFrameObject *cache_frame_function = NULL; 151     static PyFrameObject *cache_frame_function = NULL;
171 152
172     PyFrameObject *frame_function; 153     PyFrameObject *frame_function;
173 154
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  
280     tmp_assign_source_3 = MAKE_ITERATOR( tmp_iter_arg_2 );
281     if ( tmp_assign_source_3 == NULL )
282     {
283         assert( ERROR_OCCURRED() );
284  
285         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
286  
287  
288         exception_lineno = 30;
289         goto try_except_handler_2;
290     }
291     assert( tmp_tuple_unpack_1__source_iter == NULL );
292     tmp_tuple_unpack_1__source_iter = tmp_assign_source_3;
293  
294     // Tried code:
295     tmp_unpack_1 = tmp_tuple_unpack_1__source_iter;
296  
297     tmp_assign_source_4 = UNPACK_NEXT( tmp_unpack_1, 0, 2 );
298     if ( tmp_assign_source_4 == NULL )
299     {
300         if ( !ERROR_OCCURRED() )
301         {
302             exception_type = PyExc_StopIteration;
303             Py_INCREF( exception_type );
304             exception_value = NULL;
305             exception_tb = NULL;
306         }
307         else
308         {
309             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
310         }
311  
312  
313         exception_lineno = 30;
314         goto try_except_handler_3;
315     }
316     assert( tmp_tuple_unpack_1__element_1 == NULL );
317     tmp_tuple_unpack_1__element_1 = tmp_assign_source_4;
318  
319     tmp_unpack_2 = tmp_tuple_unpack_1__source_iter;
320  
321     tmp_assign_source_5 = UNPACK_NEXT( tmp_unpack_2, 1, 2 );
322     if ( tmp_assign_source_5 == NULL )
323     {
324         if ( !ERROR_OCCURRED() )
325         {
326             exception_type = PyExc_StopIteration;
327             Py_INCREF( exception_type );
328             exception_value = NULL;
329             exception_tb = NULL;
330         }
331         else
332         {
333             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
334         }
335  
336  
337         exception_lineno = 30;
338         goto try_except_handler_3;
339     }
340     assert( tmp_tuple_unpack_1__element_2 == NULL );
341     tmp_tuple_unpack_1__element_2 = tmp_assign_source_5;
342  
343     tmp_iterator_name_1 = tmp_tuple_unpack_1__source_iter;
344  
345     // Check if iterator has left-over elements.
346     CHECK_OBJECT( tmp_iterator_name_1 ); assert( HAS_ITERNEXT( tmp_iterator_name_1 ) );
347  
348     tmp_iterator_attempt = (*Py_TYPE( tmp_iterator_name_1 )->tp_iternext)( tmp_iterator_name_1 );
349  
350     if (likely( tmp_iterator_attempt == NULL ))
351     {
352         PyObject *error = GET_ERROR_OCCURRED();
353  
354         if ( error != NULL )
355         {
356             if ( EXCEPTION_MATCH_BOOL_SINGLE( error, PyExc_StopIteration ))
357             {
358                 CLEAR_ERROR_OCCURRED();
359             }
360             else
361             {
362                 FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
363  
364                 goto try_except_handler_3;
365             }
366         }
367     }
368     else
369     {
370         Py_DECREF( tmp_iterator_attempt );
371  
372         // TODO: Could avoid PyErr_Format.
373 #if PYTHON_VERSION < 300
374         PyErr_Format( PyExc_ValueError, "too many values to unpack" );
375 #else
376         PyErr_Format( PyExc_ValueError, "too many values to unpack (expected 2)" );
377 #endif
378         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
379  
380         goto try_except_handler_3;
381     }
382     goto try_end_1;
383     // Exception handler code:
384     try_except_handler_3:;
385     exception_keeper_type_1 = exception_type;
386     exception_keeper_value_1 = exception_value;
387     exception_keeper_tb_1 = exception_tb;
388     exception_keeper_lineno_1 = exception_lineno;
389     exception_type = NULL;
390     exception_value = NULL;
391     exception_tb = NULL;
392     exception_lineno = -1;
393  
394     Py_XDECREF( tmp_tuple_unpack_1__source_iter );
395     tmp_tuple_unpack_1__source_iter = NULL;
396  
397     // Re-raise.
398     exception_type = exception_keeper_type_1;
399     exception_value = exception_keeper_value_1;
400     exception_tb = exception_keeper_tb_1;
401     exception_lineno = exception_keeper_lineno_1;
402  
403     goto try_except_handler_2;
404     // End of try:
405     try_end_1:;
406     goto try_end_2;
407     // Exception handler code:
408     try_except_handler_2:;
409     exception_keeper_type_2 = exception_type;
410     exception_keeper_value_2 = exception_value;
411     exception_keeper_tb_2 = exception_tb;
412     exception_keeper_lineno_2 = exception_lineno;
413     exception_type = NULL;
414     exception_value = NULL;
415     exception_tb = NULL;
416     exception_lineno = -1;
417  
418     Py_XDECREF( tmp_tuple_unpack_1__element_1 );
419     tmp_tuple_unpack_1__element_1 = NULL;
420  
421     Py_XDECREF( tmp_tuple_unpack_1__element_2 );
422     tmp_tuple_unpack_1__element_2 = NULL;
423  
424     // Re-raise.
425     exception_type = exception_keeper_type_2;
426     exception_value = exception_keeper_value_2;
427     exception_tb = exception_keeper_tb_2;
428     exception_lineno = exception_keeper_lineno_2;
429  
430     goto frame_exception_exit_1;
431     // End of try:
432     try_end_2:;
433     Py_XDECREF( tmp_tuple_unpack_1__source_iter );
434     tmp_tuple_unpack_1__source_iter = NULL;
435  
436     tmp_assign_source_6 = tmp_tuple_unpack_1__element_1;
437  
438     assert( var_a == NULL );
439     Py_INCREF( tmp_assign_source_6 );
440     var_a = tmp_assign_source_6;
441  
442     Py_XDECREF( tmp_tuple_unpack_1__element_1 );
443     tmp_tuple_unpack_1__element_1 = NULL;
444  
445     tmp_assign_source_7 = tmp_tuple_unpack_1__element_2;
446  
447     assert( var_b == NULL );
448     Py_INCREF( tmp_assign_source_7 );
449     var_b = tmp_assign_source_7;
450  
451     Py_XDECREF( tmp_tuple_unpack_1__element_2 );
452     tmp_tuple_unpack_1__element_2 = NULL;
453  
454     Py_XDECREF( tmp_tuple_unpack_1__element_1 );
455     tmp_tuple_unpack_1__element_1 = NULL;
456  
457     Py_XDECREF( tmp_tuple_unpack_1__element_2 );
458     tmp_tuple_unpack_1__element_2 = NULL;
459  
460     tmp_return_value = PyTuple_New( 2 );
461     tmp_tuple_element_1 = var_a;
462  
463     if ( tmp_tuple_element_1 == NULL )
464     {
465         Py_DECREF( tmp_return_value );
466         exception_type = PyExc_UnboundLocalError;
467         Py_INCREF( exception_type );
468         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "a" );
469         exception_tb = NULL;
470         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
471         CHAIN_EXCEPTION( exception_value );
472  
473         exception_lineno = 36;
474         goto frame_exception_exit_1;
475     }
476  
477     Py_INCREF( tmp_tuple_element_1 );
478     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
479     tmp_tuple_element_1 = var_b;
480  
481     if ( tmp_tuple_element_1 == NULL )
482     {
483         Py_DECREF( tmp_return_value );
484         exception_type = PyExc_UnboundLocalError;
485         Py_INCREF( exception_type );
486         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "b" );
487         exception_tb = NULL;
488         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
489         CHAIN_EXCEPTION( exception_value );
490  
491         exception_lineno = 36;
492         goto frame_exception_exit_1;
493     }
494  
495     Py_INCREF( tmp_tuple_element_1 );
496     PyTuple_SET_ITEM( tmp_return_value, 1, tmp_tuple_element_1 );
497     goto frame_return_exit_1;
498 258
499 #if 0 259 #if 0
500     RESTORE_FRAME_EXCEPTION( frame_function ); 260     RESTORE_FRAME_EXCEPTION( frame_function );
501 #endif 261 #endif
502     // Put the previous frame back on top. 262     // Put the previous frame back on top.
504 #if PYTHON_VERSION >= 340 264 #if PYTHON_VERSION >= 340
505     frame_function->f_executing -= 1; 265     frame_function->f_executing -= 1;
506 #endif 266 #endif
507     Py_DECREF( frame_function ); 267     Py_DECREF( frame_function );
508     goto frame_no_exception_1; 268     goto frame_no_exception_1;
n 509   n
510     frame_return_exit_1:;
511 #if 0
512     RESTORE_FRAME_EXCEPTION( frame_function );
513 #endif
514     popFrameStack();
515 #if PYTHON_VERSION >= 340
516     frame_function->f_executing -= 1;
517 #endif
518     Py_DECREF( frame_function );
519     goto try_return_handler_1;
520 269
521     frame_exception_exit_1:; 270     frame_exception_exit_1:;
522 #if 0 271 #if 0
523     RESTORE_FRAME_EXCEPTION( frame_function ); 272     RESTORE_FRAME_EXCEPTION( frame_function );
524 #endif 273 #endif
604     // Return the error. 353     // Return the error.
605     goto try_except_handler_1; 354     goto try_except_handler_1;
606 355
607     frame_no_exception_1:; 356     frame_no_exception_1:;
608 357
n n 358     tmp_assign_source_3 = var_c;
359  
360     if ( tmp_assign_source_3 == NULL )
361     {
362  
363         exception_type = PyExc_UnboundLocalError;
364         Py_INCREF( exception_type );
365         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "c" );
366         exception_tb = NULL;
367         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
368         CHAIN_EXCEPTION( exception_value );
369  
370  
371         goto try_except_handler_1;
372     }
373  
374     assert( var_a == NULL );
375     Py_INCREF( tmp_assign_source_3 );
376     var_a = tmp_assign_source_3;
377  
378     tmp_assign_source_4 = var_c;
379  
380     if ( tmp_assign_source_4 == NULL )
381     {
382  
383         exception_type = PyExc_UnboundLocalError;
384         Py_INCREF( exception_type );
385         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "c" );
386         exception_tb = NULL;
387         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
388         CHAIN_EXCEPTION( exception_value );
389  
390  
391         goto try_except_handler_1;
392     }
393  
394     assert( var_b == NULL );
395     Py_INCREF( tmp_assign_source_4 );
396     var_b = tmp_assign_source_4;
397  
398     tmp_return_value = PyTuple_New( 2 );
399     tmp_tuple_element_1 = var_a;
400  
401     Py_INCREF( tmp_tuple_element_1 );
402     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
403     tmp_tuple_element_1 = var_b;
404  
405     Py_INCREF( tmp_tuple_element_1 );
406     PyTuple_SET_ITEM( tmp_return_value, 1, tmp_tuple_element_1 );
407     goto try_return_handler_1;
609     // tried codes exits in all cases 408     // tried codes exits in all cases
610     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 409     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
611     return NULL; 410     return NULL;
612     // Return handler code: 411     // Return handler code:
613     try_return_handler_1:; 412     try_return_handler_1:;
624     var_b = NULL; 423     var_b = NULL;
625 424
626     goto function_return_exit; 425     goto function_return_exit;
627     // Exception handler code: 426     // Exception handler code:
628     try_except_handler_1:; 427     try_except_handler_1:;
n 629     exception_keeper_type_3 = exception_type; n 428     exception_keeper_type_1 = exception_type;
630     exception_keeper_value_3 = exception_value; 429     exception_keeper_value_1 = exception_value;
631     exception_keeper_tb_3 = exception_tb; 430     exception_keeper_tb_1 = exception_tb;
632     exception_keeper_lineno_3 = exception_lineno; 431     exception_keeper_lineno_1 = exception_lineno;
633     exception_type = NULL; 432     exception_type = NULL;
634     exception_value = NULL; 433     exception_value = NULL;
635     exception_tb = NULL; 434     exception_tb = NULL;
636     exception_lineno = -1; 435     exception_lineno = -1;
637 436
638     Py_XDECREF( var_c ); 437     Py_XDECREF( var_c );
639     var_c = NULL; 438     var_c = NULL;
640 439
n 641     Py_XDECREF( var_iterator ); n
642     var_iterator = NULL;
643  
644     Py_XDECREF( var_a );
645     var_a = NULL;
646  
647     Py_XDECREF( var_b );
648     var_b = NULL;
649  
650     // Re-raise. 440     // Re-raise.
t 651     exception_type = exception_keeper_type_3; t 441     exception_type = exception_keeper_type_1;
652     exception_value = exception_keeper_value_3; 442     exception_value = exception_keeper_value_1;
653     exception_tb = exception_keeper_tb_3; 443     exception_tb = exception_keeper_tb_1;
654     exception_lineno = exception_keeper_lineno_3; 444     exception_lineno = exception_keeper_lineno_1;
655 445
656     goto function_exception_exit; 446     goto function_exception_exit;
657     // End of try: 447     // End of try:
658 448
659     // Return statement must have exited already. 449     // Return statement must have exited already.