Construct UnpackIterator

Performance Diagrams

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