Construct UnpackIterator

Performance Diagrams

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