Construct UnpackIterator

Performance Diagrams

Construct UnpackIterator 001000000100000020000002000000300000030000004000000400000050000005000000600000060000007000000700000080000008000000900000090000001000000010000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)1099981288.95192307692307257.0CPython 2.76309170242.31730769230768362.37723753124845Nuitka (master)6310239395.6826923076923362.3532219984236Nuitka (develop)6298863549.0480769230769362.60878860405137Nuitka (factory)Construct UnpackIteratorTicks Construct UnpackIterator 001000000100000020000002000000300000030000004000000400000050000005000000600000060000007000000700000080000008000000900000090000001000000010000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)1014156788.95192307692307257.0CPython 3.57249964242.31730769230768327.45849891836247Nuitka (master)7250329395.6826923076923327.4496051137478Nuitka (develop)7250445549.0480769230769327.44677858954145Nuitka (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
135     // Local variable declarations. 135     // Local variable declarations.
136     PyObject *var_a = NULL; 136     PyObject *var_a = NULL;
137     PyObject *var_b = NULL; 137     PyObject *var_b = NULL;
138     PyObject *var_c = NULL; 138     PyObject *var_c = NULL;
139     PyObject *var_iterator = NULL; 139     PyObject *var_iterator = NULL;
n 140     PyObject *tmp_tuple_unpack_1__element_1 = NULL; n
141     PyObject *tmp_tuple_unpack_1__element_2 = NULL;
142     PyObject *tmp_tuple_unpack_1__source_iter = NULL;
143     struct Nuitka_FrameObject *frame_bd4e03c87a49c75b45c5c68fdf4cfcf7; 140     struct Nuitka_FrameObject *frame_bd4e03c87a49c75b45c5c68fdf4cfcf7;
144     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL; 141     NUITKA_MAY_BE_UNUSED char const *type_description_1 = 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;
n 149     PyObject *tmp_iterator_attempt; n 146     static struct Nuitka_FrameObject *cache_frame_bd4e03c87a49c75b45c5c68fdf4cfcf7 = NULL;
147     PyObject *tmp_return_value = NULL;
150     PyObject *exception_keeper_type_1; 148     PyObject *exception_keeper_type_1;
151     PyObject *exception_keeper_value_1; 149     PyObject *exception_keeper_value_1;
152     PyTracebackObject *exception_keeper_tb_1; 150     PyTracebackObject *exception_keeper_tb_1;
153     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 151     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
n 154     PyObject *exception_keeper_type_2; n
155     PyObject *exception_keeper_value_2;
156     PyTracebackObject *exception_keeper_tb_2;
157     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_2;
158     static struct Nuitka_FrameObject *cache_frame_bd4e03c87a49c75b45c5c68fdf4cfcf7 = NULL;
159     PyObject *tmp_return_value = NULL;
160     PyObject *exception_keeper_type_3;
161     PyObject *exception_keeper_value_3;
162     PyTracebackObject *exception_keeper_tb_3;
163     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
164 152
165     // Actual function body. 153     // Actual function body.
166     // Tried code: 154     // Tried code:
167     MAKE_OR_REUSE_FRAME( cache_frame_bd4e03c87a49c75b45c5c68fdf4cfcf7, codeobj_bd4e03c87a49c75b45c5c68fdf4cfcf7, module___main__, sizeof(void *)+sizeof(void *)+sizeof(void *)+sizeof(void *) ); 155     MAKE_OR_REUSE_FRAME( cache_frame_bd4e03c87a49c75b45c5c68fdf4cfcf7, codeobj_bd4e03c87a49c75b45c5c68fdf4cfcf7, module___main__, sizeof(void *)+sizeof(void *)+sizeof(void *)+sizeof(void *) );
168     frame_bd4e03c87a49c75b45c5c68fdf4cfcf7 = cache_frame_bd4e03c87a49c75b45c5c68fdf4cfcf7; 156     frame_bd4e03c87a49c75b45c5c68fdf4cfcf7 = cache_frame_bd4e03c87a49c75b45c5c68fdf4cfcf7;
258             goto frame_exception_exit_1; 246             goto frame_exception_exit_1;
259         } 247         }
260         assert( var_iterator == NULL ); 248         assert( var_iterator == NULL );
261         var_iterator = tmp_assign_source_2; 249         var_iterator = tmp_assign_source_2;
262     } 250     }
n 263     // Tried code: n
264     {
265         PyObject *tmp_assign_source_3;
266         PyObject *tmp_iter_arg_2;
267         CHECK_OBJECT( var_iterator );
268         tmp_iter_arg_2 = var_iterator;
269         tmp_assign_source_3 = MAKE_ITERATOR( tmp_iter_arg_2 );
270         if ( tmp_assign_source_3 == NULL )
271         {
272             assert( ERROR_OCCURRED() );
273  
274             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
275  
276  
277             exception_lineno = 30;
278             type_description_1 = "oooo";
279             goto try_except_handler_2;
280         }
281         assert( tmp_tuple_unpack_1__source_iter == NULL );
282         tmp_tuple_unpack_1__source_iter = tmp_assign_source_3;
283     }
284     // Tried code:
285     {
286         PyObject *tmp_assign_source_4;
287         PyObject *tmp_unpack_1;
288         CHECK_OBJECT( tmp_tuple_unpack_1__source_iter );
289         tmp_unpack_1 = tmp_tuple_unpack_1__source_iter;
290         tmp_assign_source_4 = UNPACK_NEXT( tmp_unpack_1, 0, 2 );
291         if ( tmp_assign_source_4 == NULL )
292         {
293             if ( !ERROR_OCCURRED() )
294             {
295                 exception_type = PyExc_StopIteration;
296                 Py_INCREF( exception_type );
297                 exception_value = NULL;
298                 exception_tb = NULL;
299             }
300             else
301             {
302                 FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
303             }
304  
305  
306             type_description_1 = "oooo";
307             exception_lineno = 30;
308             goto try_except_handler_3;
309         }
310         assert( tmp_tuple_unpack_1__element_1 == NULL );
311         tmp_tuple_unpack_1__element_1 = tmp_assign_source_4;
312     }
313     {
314         PyObject *tmp_assign_source_5;
315         PyObject *tmp_unpack_2;
316         CHECK_OBJECT( tmp_tuple_unpack_1__source_iter );
317         tmp_unpack_2 = tmp_tuple_unpack_1__source_iter;
318         tmp_assign_source_5 = UNPACK_NEXT( tmp_unpack_2, 1, 2 );
319         if ( tmp_assign_source_5 == NULL )
320         {
321             if ( !ERROR_OCCURRED() )
322             {
323                 exception_type = PyExc_StopIteration;
324                 Py_INCREF( exception_type );
325                 exception_value = NULL;
326                 exception_tb = NULL;
327             }
328             else
329             {
330                 FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
331             }
332  
333  
334             type_description_1 = "oooo";
335             exception_lineno = 30;
336             goto try_except_handler_3;
337         }
338         assert( tmp_tuple_unpack_1__element_2 == NULL );
339         tmp_tuple_unpack_1__element_2 = tmp_assign_source_5;
340     }
341     {
342         PyObject *tmp_iterator_name_1;
343         CHECK_OBJECT( tmp_tuple_unpack_1__source_iter );
344         tmp_iterator_name_1 = tmp_tuple_unpack_1__source_iter;
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                     type_description_1 = "oooo";
365                     exception_lineno = 30;
366                     goto try_except_handler_3;
367                 }
368             }
369         }
370         else
371         {
372             Py_DECREF( tmp_iterator_attempt );
373  
374             // TODO: Could avoid PyErr_Format.
375 #if PYTHON_VERSION < 300
376             PyErr_Format( PyExc_ValueError, "too many values to unpack" );
377 #else
378             PyErr_Format( PyExc_ValueError, "too many values to unpack (expected 2)" );
379 #endif
380             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
381  
382             type_description_1 = "oooo";
383             exception_lineno = 30;
384             goto try_except_handler_3;
385         }
386     }
387     goto try_end_1;
388     // Exception handler code:
389     try_except_handler_3:;
390     exception_keeper_type_1 = exception_type;
391     exception_keeper_value_1 = exception_value;
392     exception_keeper_tb_1 = exception_tb;
393     exception_keeper_lineno_1 = exception_lineno;
394     exception_type = NULL;
395     exception_value = NULL;
396     exception_tb = NULL;
397     exception_lineno = 0;
398  
399     CHECK_OBJECT( (PyObject *)tmp_tuple_unpack_1__source_iter );
400     Py_DECREF( 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 251
440 #if 0 252 #if 0
441     RESTORE_FRAME_EXCEPTION( frame_bd4e03c87a49c75b45c5c68fdf4cfcf7 ); 253     RESTORE_FRAME_EXCEPTION( frame_bd4e03c87a49c75b45c5c68fdf4cfcf7 );
442 #endif 254 #endif
443 255
486 298
487     // Return the error. 299     // Return the error.
488     goto try_except_handler_1; 300     goto try_except_handler_1;
489 301
490     frame_no_exception_1:; 302     frame_no_exception_1:;
n 491     CHECK_OBJECT( (PyObject *)tmp_tuple_unpack_1__source_iter ); n
492     Py_DECREF( tmp_tuple_unpack_1__source_iter );
493     tmp_tuple_unpack_1__source_iter = NULL;
494  
495     { 303     {
n 496         PyObject *tmp_assign_source_6; n 304         PyObject *tmp_assign_source_3;
497         CHECK_OBJECT( tmp_tuple_unpack_1__element_1 ); 305         CHECK_OBJECT( var_c );
498         tmp_assign_source_6 = tmp_tuple_unpack_1__element_1; 306         tmp_assign_source_3 = var_c;
499         assert( var_a == NULL ); 307         assert( var_a == NULL );
n 500         Py_INCREF( tmp_assign_source_6 ); n 308         Py_INCREF( tmp_assign_source_3 );
501         var_a = tmp_assign_source_6; 309         var_a = tmp_assign_source_3;
502     }
503     Py_XDECREF( tmp_tuple_unpack_1__element_1 );
504     tmp_tuple_unpack_1__element_1 = NULL;
505  
506     { 310     }
311     {
507         PyObject *tmp_assign_source_7; 312         PyObject *tmp_assign_source_4;
508         CHECK_OBJECT( tmp_tuple_unpack_1__element_2 ); 313         CHECK_OBJECT( var_c );
509         tmp_assign_source_7 = tmp_tuple_unpack_1__element_2; 314         tmp_assign_source_4 = var_c;
510         assert( var_b == NULL ); 315         assert( var_b == NULL );
n 511         Py_INCREF( tmp_assign_source_7 ); n 316         Py_INCREF( tmp_assign_source_4 );
512         var_b = tmp_assign_source_7; 317         var_b = tmp_assign_source_4;
513     } 318     }
n 514     Py_XDECREF( tmp_tuple_unpack_1__element_2 ); n
515     tmp_tuple_unpack_1__element_2 = NULL;
516  
517     { 319     {
518         PyObject *tmp_tuple_element_1; 320         PyObject *tmp_tuple_element_1;
519         CHECK_OBJECT( var_a ); 321         CHECK_OBJECT( var_a );
520         tmp_tuple_element_1 = var_a; 322         tmp_tuple_element_1 = var_a;
521         tmp_return_value = PyTuple_New( 2 ); 323         tmp_return_value = PyTuple_New( 2 );
549     var_iterator = NULL; 351     var_iterator = NULL;
550 352
551     goto function_return_exit; 353     goto function_return_exit;
552     // Exception handler code: 354     // Exception handler code:
553     try_except_handler_1:; 355     try_except_handler_1:;
n 554     exception_keeper_type_3 = exception_type; n 356     exception_keeper_type_1 = exception_type;
555     exception_keeper_value_3 = exception_value; 357     exception_keeper_value_1 = exception_value;
556     exception_keeper_tb_3 = exception_tb; 358     exception_keeper_tb_1 = exception_tb;
557     exception_keeper_lineno_3 = exception_lineno; 359     exception_keeper_lineno_1 = exception_lineno;
558     exception_type = NULL; 360     exception_type = NULL;
559     exception_value = NULL; 361     exception_value = NULL;
560     exception_tb = NULL; 362     exception_tb = NULL;
561     exception_lineno = 0; 363     exception_lineno = 0;
562 364
563     Py_XDECREF( var_c ); 365     Py_XDECREF( var_c );
564     var_c = NULL; 366     var_c = NULL;
565 367
n 566     Py_XDECREF( var_iterator ); n
567     var_iterator = NULL;
568  
569     // Re-raise. 368     // Re-raise.
t 570     exception_type = exception_keeper_type_3; t 369     exception_type = exception_keeper_type_1;
571     exception_value = exception_keeper_value_3; 370     exception_value = exception_keeper_value_1;
572     exception_tb = exception_keeper_tb_3; 371     exception_tb = exception_keeper_tb_1;
573     exception_lineno = exception_keeper_lineno_3; 372     exception_lineno = exception_keeper_lineno_1;
574 373
575     goto function_exception_exit; 374     goto function_exception_exit;
576     // End of try: 375     // End of try:
577 376
578     // Return statement must have exited already. 377     // Return statement must have exited already.