Construct UnpackIterator

Performance Diagrams

Construct UnpackIterator 001000000100000020000002000000300000030000004000000400000050000005000000600000060000007000000700000080000008000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)839815789.78846153846155257.00000000000006CPython 2.76499439244.59615384615387312.8696900815446Nuitka (master)6499217399.4038461538462312.87622242136445Nuitka (develop)6499669554.2115384615385312.86292234209157Nuitka (factory)Construct UnpackIteratorTicks Construct UnpackIterator 0010000001000000200000020000003000000300000040000004000000500000050000006000000600000070000007000000800000080000009000000900000010000000100000001100000011000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)1124157388.95192307692307257.0CPython 3.57601141242.31730769230768337.02498883796375Nuitka (master)7601215395.6826923076923337.0233621493801Nuitka (develop)7600373549.0480769230769337.0418712275888Nuitka (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_8b19ef9c89d0ea05ac26831b3ec03319 = NULL; 158     static struct Nuitka_FrameObject *cache_frame_8b19ef9c89d0ea05ac26831b3ec03319 = NULL;
178 159
179     struct Nuitka_FrameObject *frame_8b19ef9c89d0ea05ac26831b3ec03319; 160     struct Nuitka_FrameObject *frame_8b19ef9c89d0ea05ac26831b3ec03319;
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     Py_XDECREF( tmp_tuple_unpack_1__source_iter );
401     tmp_tuple_unpack_1__source_iter = NULL;
402  
403     // Re-raise.
404     exception_type = exception_keeper_type_1;
405     exception_value = exception_keeper_value_1;
406     exception_tb = exception_keeper_tb_1;
407     exception_lineno = exception_keeper_lineno_1;
408  
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_1 = "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_1 = "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 253
509 #if 0 254 #if 0
510     RESTORE_FRAME_EXCEPTION( frame_8b19ef9c89d0ea05ac26831b3ec03319 ); 255     RESTORE_FRAME_EXCEPTION( frame_8b19ef9c89d0ea05ac26831b3ec03319 );
511 #endif 256 #endif
512 257
513     // Put the previous frame back on top. 258     // Put the previous frame back on top.
514     popFrameStack(); 259     popFrameStack();
515 260
516     goto frame_no_exception_1; 261     goto frame_no_exception_1;
n 517   n
518     frame_return_exit_1:;
519 #if 0
520     RESTORE_FRAME_EXCEPTION( frame_8b19ef9c89d0ea05ac26831b3ec03319 );
521 #endif
522  
523     // Put the previous frame back on top.
524     popFrameStack();
525  
526     goto try_return_handler_1;
527 262
528     frame_exception_exit_1:; 263     frame_exception_exit_1:;
529 264
530 #if 0 265 #if 0
531     RESTORE_FRAME_EXCEPTION( frame_8b19ef9c89d0ea05ac26831b3ec03319 ); 266     RESTORE_FRAME_EXCEPTION( frame_8b19ef9c89d0ea05ac26831b3ec03319 );
566     // Return the error. 301     // Return the error.
567     goto try_except_handler_1; 302     goto try_except_handler_1;
568 303
569     frame_no_exception_1:; 304     frame_no_exception_1:;
570 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;
571     // tried codes exits in all cases 332     // tried codes exits in all cases
572     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 333     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
573     return NULL; 334     return NULL;
574     // Return handler code: 335     // Return handler code:
575     try_return_handler_1:; 336     try_return_handler_1:;
n n 337     CHECK_OBJECT( (PyObject *)var_c );
576     Py_XDECREF( var_c ); 338     Py_DECREF( var_c );
577     var_c = NULL; 339     var_c = NULL;
578 340
579     Py_XDECREF( var_iterator ); 341     Py_XDECREF( var_iterator );
580     var_iterator = NULL; 342     var_iterator = NULL;
581 343
586     var_b = NULL; 348     var_b = NULL;
587 349
588     goto function_return_exit; 350     goto function_return_exit;
589     // Exception handler code: 351     // Exception handler code:
590     try_except_handler_1:; 352     try_except_handler_1:;
n 591     exception_keeper_type_3 = exception_type; n 353     exception_keeper_type_1 = exception_type;
592     exception_keeper_value_3 = exception_value; 354     exception_keeper_value_1 = exception_value;
593     exception_keeper_tb_3 = exception_tb; 355     exception_keeper_tb_1 = exception_tb;
594     exception_keeper_lineno_3 = exception_lineno; 356     exception_keeper_lineno_1 = exception_lineno;
595     exception_type = NULL; 357     exception_type = NULL;
596     exception_value = NULL; 358     exception_value = NULL;
597     exception_tb = NULL; 359     exception_tb = NULL;
598     exception_lineno = 0; 360     exception_lineno = 0;
599 361
600     Py_XDECREF( var_c ); 362     Py_XDECREF( var_c );
601     var_c = NULL; 363     var_c = NULL;
602 364
n 603     Py_XDECREF( var_iterator ); n
604     var_iterator = NULL;
605  
606     Py_XDECREF( var_a );
607     var_a = NULL;
608  
609     Py_XDECREF( var_b );
610     var_b = NULL;
611  
612     // Re-raise. 365     // Re-raise.
t 613     exception_type = exception_keeper_type_3; t 366     exception_type = exception_keeper_type_1;
614     exception_value = exception_keeper_value_3; 367     exception_value = exception_keeper_value_1;
615     exception_tb = exception_keeper_tb_3; 368     exception_tb = exception_keeper_tb_1;
616     exception_lineno = exception_keeper_lineno_3; 369     exception_lineno = exception_keeper_lineno_1;
617 370
618     goto function_exception_exit; 371     goto function_exception_exit;
619     // End of try: 372     // End of try:
620 373
621     // Return statement must have exited already. 374     // Return statement must have exited already.