Construct UnpackIterator

Performance Diagrams

Construct UnpackIterator 0010000001000000200000020000003000000300000040000004000000500000050000006000000600000070000007000000800000080000009000000900000010000000100000001100000011000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)1114998988.95192307692307257.0CPython 2.76200464242.31730769230768366.6955139631493Nuitka (master)6200498395.6826923076923366.69476042670397Nuitka (develop)6204190549.0480769230769366.61293523387195Nuitka (factory)Construct UnpackIteratorTicks Construct UnpackIterator 001000000100000020000002000000300000030000004000000400000050000005000000600000060000007000000700000080000008000000900000090000001000000010000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)1014115988.95192307692307257.0CPython 3.57000928242.31730769230768333.5197933831975Nuitka (master)7000434395.6826923076923333.5318309619397Nuitka (develop)6999326549.0480769230769333.55883022762066Nuitka (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

import itertools
for x in itertools.repeat(None, 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

import itertools
for x in itertools.repeat(None, 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 import itertools 38 import itertools
39 for x in itertools.repeat(None, 50000): 39 for x in itertools.repeat(None, 50000):

Context Diff of Generated Code


Construct
Baseline
137     // Local variable declarations. 137     // Local variable declarations.
138     PyObject *var_c = NULL; 138     PyObject *var_c = NULL;
139     PyObject *var_iterator = NULL; 139     PyObject *var_iterator = NULL;
140     PyObject *var_a = NULL; 140     PyObject *var_a = NULL;
141     PyObject *var_b = NULL; 141     PyObject *var_b = NULL;
n 142     PyObject *tmp_tuple_unpack_1__element_1 = NULL; n
143     PyObject *tmp_tuple_unpack_1__element_2 = NULL;
144     PyObject *tmp_tuple_unpack_1__source_iter = NULL;
145     PyObject *exception_type = NULL; 142     PyObject *exception_type = NULL;
146     PyObject *exception_value = NULL; 143     PyObject *exception_value = NULL;
147     PyTracebackObject *exception_tb = NULL; 144     PyTracebackObject *exception_tb = NULL;
148     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 145     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
149     PyObject *exception_keeper_type_1; 146     PyObject *exception_keeper_type_1;
150     PyObject *exception_keeper_value_1; 147     PyObject *exception_keeper_value_1;
151     PyTracebackObject *exception_keeper_tb_1; 148     PyTracebackObject *exception_keeper_tb_1;
152     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 149     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
n 153     PyObject *exception_keeper_type_2; n
154     PyObject *exception_keeper_value_2;
155     PyTracebackObject *exception_keeper_tb_2;
156     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_2;
157     PyObject *exception_keeper_type_3;
158     PyObject *exception_keeper_value_3;
159     PyTracebackObject *exception_keeper_tb_3;
160     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
161     PyObject *tmp_assign_source_1; 150     PyObject *tmp_assign_source_1;
162     PyObject *tmp_assign_source_2; 151     PyObject *tmp_assign_source_2;
163     PyObject *tmp_assign_source_3; 152     PyObject *tmp_assign_source_3;
164     PyObject *tmp_assign_source_4; 153     PyObject *tmp_assign_source_4;
n 165     PyObject *tmp_assign_source_5; n
166     PyObject *tmp_assign_source_6;
167     PyObject *tmp_assign_source_7;
168     PyObject *tmp_iter_arg_1; 154     PyObject *tmp_iter_arg_1;
n 169     PyObject *tmp_iter_arg_2; n
170     PyObject *tmp_iterator_attempt;
171     PyObject *tmp_iterator_name_1;
172     PyObject *tmp_return_value; 155     PyObject *tmp_return_value;
173     PyObject *tmp_tuple_element_1; 156     PyObject *tmp_tuple_element_1;
n 174     PyObject *tmp_unpack_1; n
175     PyObject *tmp_unpack_2;
176     PyObject *tmp_xrange_low_1; 157     PyObject *tmp_xrange_low_1;
177     static struct Nuitka_FrameObject *cache_frame_26d300740e1fb22760351eb9e2a05904 = NULL; 158     static struct Nuitka_FrameObject *cache_frame_26d300740e1fb22760351eb9e2a05904 = NULL;
178 159
179     struct Nuitka_FrameObject *frame_26d300740e1fb22760351eb9e2a05904; 160     struct Nuitka_FrameObject *frame_26d300740e1fb22760351eb9e2a05904;
180 161
267         goto frame_exception_exit_1; 248         goto frame_exception_exit_1;
268     } 249     }
269     assert( var_iterator == NULL ); 250     assert( var_iterator == NULL );
270     var_iterator = tmp_assign_source_2; 251     var_iterator = tmp_assign_source_2;
271 252
n 272     // Tried code: n
273     tmp_iter_arg_2 = var_iterator;
274  
275     CHECK_OBJECT( tmp_iter_arg_2 );
276     tmp_assign_source_3 = MAKE_ITERATOR( tmp_iter_arg_2 );
277     if ( tmp_assign_source_3 == NULL )
278     {
279         assert( ERROR_OCCURRED() );
280  
281         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
282  
283  
284         exception_lineno = 30;
285         type_description_1 = "oooo";
286         goto try_except_handler_2;
287     }
288     assert( tmp_tuple_unpack_1__source_iter == NULL );
289     tmp_tuple_unpack_1__source_iter = tmp_assign_source_3;
290  
291     // Tried code:
292     tmp_unpack_1 = tmp_tuple_unpack_1__source_iter;
293  
294     CHECK_OBJECT( tmp_unpack_1 );
295     tmp_assign_source_4 = UNPACK_NEXT( tmp_unpack_1, 0, 2 );
296     if ( tmp_assign_source_4 == NULL )
297     {
298         if ( !ERROR_OCCURRED() )
299         {
300             exception_type = PyExc_StopIteration;
301             Py_INCREF( exception_type );
302             exception_value = NULL;
303             exception_tb = NULL;
304         }
305         else
306         {
307             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
308         }
309  
310  
311         type_description_1 = "oooo";
312         exception_lineno = 30;
313         goto try_except_handler_3;
314     }
315     assert( tmp_tuple_unpack_1__element_1 == NULL );
316     tmp_tuple_unpack_1__element_1 = tmp_assign_source_4;
317  
318     tmp_unpack_2 = tmp_tuple_unpack_1__source_iter;
319  
320     CHECK_OBJECT( tmp_unpack_2 );
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         type_description_1 = "oooo";
338         exception_lineno = 30;
339         goto try_except_handler_3;
340     }
341     assert( tmp_tuple_unpack_1__element_2 == NULL );
342     tmp_tuple_unpack_1__element_2 = tmp_assign_source_5;
343  
344     tmp_iterator_name_1 = tmp_tuple_unpack_1__source_iter;
345  
346     CHECK_OBJECT( tmp_iterator_name_1 );
347     // Check if iterator has left-over elements.
348     CHECK_OBJECT( tmp_iterator_name_1 ); assert( HAS_ITERNEXT( tmp_iterator_name_1 ) );
349  
350     tmp_iterator_attempt = (*Py_TYPE( tmp_iterator_name_1 )->tp_iternext)( tmp_iterator_name_1 );
351  
352     if (likely( tmp_iterator_attempt == NULL ))
353     {
354         PyObject *error = GET_ERROR_OCCURRED();
355  
356         if ( error != NULL )
357         {
358             if ( EXCEPTION_MATCH_BOOL_SINGLE( error, PyExc_StopIteration ))
359             {
360                 CLEAR_ERROR_OCCURRED();
361             }
362             else
363             {
364                 FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
365  
366                 type_description_1 = "oooo";
367                 exception_lineno = 30;
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_1 = "oooo";
385         exception_lineno = 30;
386         goto try_except_handler_3;
387     }
388     goto try_end_1;
389     // Exception handler code:
390     try_except_handler_3:;
391     exception_keeper_type_1 = exception_type;
392     exception_keeper_value_1 = exception_value;
393     exception_keeper_tb_1 = exception_tb;
394     exception_keeper_lineno_1 = exception_lineno;
395     exception_type = NULL;
396     exception_value = NULL;
397     exception_tb = NULL;
398     exception_lineno = 0;
399  
400     CHECK_OBJECT( (PyObject *)tmp_tuple_unpack_1__source_iter );
401     Py_DECREF( tmp_tuple_unpack_1__source_iter );
402     tmp_tuple_unpack_1__source_iter = NULL;
403  
404     // Re-raise.
405     exception_type = exception_keeper_type_1;
406     exception_value = exception_keeper_value_1;
407     exception_tb = exception_keeper_tb_1;
408     exception_lineno = exception_keeper_lineno_1;
409  
410     goto try_except_handler_2;
411     // End of try:
412     try_end_1:;
413     goto try_end_2;
414     // Exception handler code:
415     try_except_handler_2:;
416     exception_keeper_type_2 = exception_type;
417     exception_keeper_value_2 = exception_value;
418     exception_keeper_tb_2 = exception_tb;
419     exception_keeper_lineno_2 = exception_lineno;
420     exception_type = NULL;
421     exception_value = NULL;
422     exception_tb = NULL;
423     exception_lineno = 0;
424  
425     Py_XDECREF( tmp_tuple_unpack_1__element_1 );
426     tmp_tuple_unpack_1__element_1 = NULL;
427  
428     Py_XDECREF( tmp_tuple_unpack_1__element_2 );
429     tmp_tuple_unpack_1__element_2 = NULL;
430  
431     // Re-raise.
432     exception_type = exception_keeper_type_2;
433     exception_value = exception_keeper_value_2;
434     exception_tb = exception_keeper_tb_2;
435     exception_lineno = exception_keeper_lineno_2;
436  
437     goto frame_exception_exit_1;
438     // End of try:
439     try_end_2:;
440     CHECK_OBJECT( (PyObject *)tmp_tuple_unpack_1__source_iter );
441     Py_DECREF( 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     tmp_return_value = PyTuple_New( 2 );
465     tmp_tuple_element_1 = var_a;
466  
467     if ( tmp_tuple_element_1 == NULL )
468     {
469         Py_DECREF( tmp_return_value );
470         exception_type = PyExc_UnboundLocalError;
471         Py_INCREF( exception_type );
472         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "a" );
473         exception_tb = NULL;
474         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
475         CHAIN_EXCEPTION( exception_value );
476  
477         exception_lineno = 36;
478         type_description_1 = "oooo";
479         goto frame_exception_exit_1;
480     }
481  
482     Py_INCREF( tmp_tuple_element_1 );
483     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
484     tmp_tuple_element_1 = var_b;
485  
486     if ( tmp_tuple_element_1 == NULL )
487     {
488         Py_DECREF( tmp_return_value );
489         exception_type = PyExc_UnboundLocalError;
490         Py_INCREF( exception_type );
491         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "b" );
492         exception_tb = NULL;
493         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
494         CHAIN_EXCEPTION( exception_value );
495  
496         exception_lineno = 36;
497         type_description_1 = "oooo";
498         goto frame_exception_exit_1;
499     }
500  
501     Py_INCREF( tmp_tuple_element_1 );
502     PyTuple_SET_ITEM( tmp_return_value, 1, tmp_tuple_element_1 );
503     goto frame_return_exit_1;
504 253
505 #if 0 254 #if 0
506     RESTORE_FRAME_EXCEPTION( frame_26d300740e1fb22760351eb9e2a05904 ); 255     RESTORE_FRAME_EXCEPTION( frame_26d300740e1fb22760351eb9e2a05904 );
507 #endif 256 #endif
508 257
509     // Put the previous frame back on top. 258     // Put the previous frame back on top.
510     popFrameStack(); 259     popFrameStack();
511 260
512     goto frame_no_exception_1; 261     goto frame_no_exception_1;
n 513   n
514     frame_return_exit_1:;
515 #if 0
516     RESTORE_FRAME_EXCEPTION( frame_26d300740e1fb22760351eb9e2a05904 );
517 #endif
518  
519     // Put the previous frame back on top.
520     popFrameStack();
521  
522     goto try_return_handler_1;
523 262
524     frame_exception_exit_1:; 263     frame_exception_exit_1:;
525 264
526 #if 0 265 #if 0
527     RESTORE_FRAME_EXCEPTION( frame_26d300740e1fb22760351eb9e2a05904 ); 266     RESTORE_FRAME_EXCEPTION( frame_26d300740e1fb22760351eb9e2a05904 );
562     // Return the error. 301     // Return the error.
563     goto try_except_handler_1; 302     goto try_except_handler_1;
564 303
565     frame_no_exception_1:; 304     frame_no_exception_1:;
566 305
n n 306     tmp_assign_source_3 = var_c;
307  
308     CHECK_OBJECT( tmp_assign_source_3 );
309     assert( var_a == NULL );
310     Py_INCREF( tmp_assign_source_3 );
311     var_a = tmp_assign_source_3;
312  
313     tmp_assign_source_4 = var_c;
314  
315     CHECK_OBJECT( tmp_assign_source_4 );
316     assert( var_b == NULL );
317     Py_INCREF( tmp_assign_source_4 );
318     var_b = tmp_assign_source_4;
319  
320     tmp_return_value = PyTuple_New( 2 );
321     tmp_tuple_element_1 = var_a;
322  
323     CHECK_OBJECT( tmp_tuple_element_1 );
324     Py_INCREF( tmp_tuple_element_1 );
325     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
326     tmp_tuple_element_1 = var_b;
327  
328     CHECK_OBJECT( tmp_tuple_element_1 );
329     Py_INCREF( tmp_tuple_element_1 );
330     PyTuple_SET_ITEM( tmp_return_value, 1, tmp_tuple_element_1 );
331     goto try_return_handler_1;
567     // tried codes exits in all cases 332     // tried codes exits in all cases
568     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 333     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
569     return NULL; 334     return NULL;
570     // Return handler code: 335     // Return handler code:
571     try_return_handler_1:; 336     try_return_handler_1:;
n n 337     CHECK_OBJECT( (PyObject *)var_c );
572     Py_XDECREF( var_c ); 338     Py_DECREF( var_c );
573     var_c = NULL; 339     var_c = NULL;
574 340
575     Py_XDECREF( var_iterator ); 341     Py_XDECREF( var_iterator );
576     var_iterator = NULL; 342     var_iterator = NULL;
577 343
582     var_b = NULL; 348     var_b = NULL;
583 349
584     goto function_return_exit; 350     goto function_return_exit;
585     // Exception handler code: 351     // Exception handler code:
586     try_except_handler_1:; 352     try_except_handler_1:;
n 587     exception_keeper_type_3 = exception_type; n 353     exception_keeper_type_1 = exception_type;
588     exception_keeper_value_3 = exception_value; 354     exception_keeper_value_1 = exception_value;
589     exception_keeper_tb_3 = exception_tb; 355     exception_keeper_tb_1 = exception_tb;
590     exception_keeper_lineno_3 = exception_lineno; 356     exception_keeper_lineno_1 = exception_lineno;
591     exception_type = NULL; 357     exception_type = NULL;
592     exception_value = NULL; 358     exception_value = NULL;
593     exception_tb = NULL; 359     exception_tb = NULL;
594     exception_lineno = 0; 360     exception_lineno = 0;
595 361
596     Py_XDECREF( var_c ); 362     Py_XDECREF( var_c );
597     var_c = NULL; 363     var_c = NULL;
598 364
n 599     Py_XDECREF( var_iterator ); n
600     var_iterator = NULL;
601  
602     Py_XDECREF( var_a );
603     var_a = NULL;
604  
605     Py_XDECREF( var_b );
606     var_b = NULL;
607  
608     // Re-raise. 365     // Re-raise.
t 609     exception_type = exception_keeper_type_3; t 366     exception_type = exception_keeper_type_1;
610     exception_value = exception_keeper_value_3; 367     exception_value = exception_keeper_value_1;
611     exception_tb = exception_keeper_tb_3; 368     exception_tb = exception_keeper_tb_1;
612     exception_lineno = exception_keeper_lineno_3; 369     exception_lineno = exception_keeper_lineno_1;
613 370
614     goto function_exception_exit; 371     goto function_exception_exit;
615     // End of try: 372     // End of try:
616 373
617     // Return statement must have exited already. 374     // Return statement must have exited already.