Construct UnpackIterator

Performance Diagrams

Construct UnpackIterator 001000000100000020000002000000300000030000004000000400000050000005000000600000060000007000000700000080000008000000900000090000001000000010000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)1055127788.95192307692307257.0CPython 2.76400523242.31730769230768354.212419989907Nuitka (master)6398669395.6826923076923354.25584145662395Nuitka (develop)6399389549.0480769230769354.2389787511028Nuitka (factory)Construct UnpackIteratorTicks Construct UnpackIterator 0010000001000000200000020000003000000300000040000004000000500000050000006000000600000070000007000000800000080000009000000900000010000000100000001100000011000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)1113885488.95192307692307257.0CPython 3.57499651242.31730769230768337.7356887017696Nuitka (master)7500335395.6826923076923337.72051416738066Nuitka (develop)7500297549.0480769230769337.721357197069Nuitka (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
134     // Local variable declarations. 134     // Local variable declarations.
135     PyObject *var_a = NULL; 135     PyObject *var_a = NULL;
136     PyObject *var_b = NULL; 136     PyObject *var_b = NULL;
137     PyObject *var_c = NULL; 137     PyObject *var_c = NULL;
138     PyObject *var_iterator = NULL; 138     PyObject *var_iterator = NULL;
n 139     PyObject *tmp_tuple_unpack_1__element_1 = NULL; n
140     PyObject *tmp_tuple_unpack_1__element_2 = NULL;
141     PyObject *tmp_tuple_unpack_1__source_iter = NULL;
142     struct Nuitka_FrameObject *frame_93a53cae61099e6802731aa3f10e0532; 139     struct Nuitka_FrameObject *frame_93a53cae61099e6802731aa3f10e0532;
143     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL; 140     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
144     PyObject *exception_type = NULL; 141     PyObject *exception_type = NULL;
145     PyObject *exception_value = NULL; 142     PyObject *exception_value = NULL;
146     PyTracebackObject *exception_tb = NULL; 143     PyTracebackObject *exception_tb = NULL;
147     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 144     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
n 148     PyObject *tmp_iterator_attempt; n 145     static struct Nuitka_FrameObject *cache_frame_93a53cae61099e6802731aa3f10e0532 = NULL;
146     PyObject *tmp_return_value = NULL;
149     PyObject *exception_keeper_type_1; 147     PyObject *exception_keeper_type_1;
150     PyObject *exception_keeper_value_1; 148     PyObject *exception_keeper_value_1;
151     PyTracebackObject *exception_keeper_tb_1; 149     PyTracebackObject *exception_keeper_tb_1;
152     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 150     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     static struct Nuitka_FrameObject *cache_frame_93a53cae61099e6802731aa3f10e0532 = NULL;
158     PyObject *tmp_return_value = NULL;
159     PyObject *exception_keeper_type_3;
160     PyObject *exception_keeper_value_3;
161     PyTracebackObject *exception_keeper_tb_3;
162     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
163 151
164     // Actual function body. 152     // Actual function body.
165     // Tried code: 153     // Tried code:
166     MAKE_OR_REUSE_FRAME(cache_frame_93a53cae61099e6802731aa3f10e0532, codeobj_93a53cae61099e6802731aa3f10e0532, module___main__, sizeof(void *)+sizeof(void *)+sizeof(void *)+sizeof(void *)); 154     MAKE_OR_REUSE_FRAME(cache_frame_93a53cae61099e6802731aa3f10e0532, codeobj_93a53cae61099e6802731aa3f10e0532, module___main__, sizeof(void *)+sizeof(void *)+sizeof(void *)+sizeof(void *));
167     frame_93a53cae61099e6802731aa3f10e0532 = cache_frame_93a53cae61099e6802731aa3f10e0532; 155     frame_93a53cae61099e6802731aa3f10e0532 = cache_frame_93a53cae61099e6802731aa3f10e0532;
255             goto frame_exception_exit_1; 243             goto frame_exception_exit_1;
256         } 244         }
257         assert(var_iterator == NULL); 245         assert(var_iterator == NULL);
258         var_iterator = tmp_assign_source_2; 246         var_iterator = tmp_assign_source_2;
259     } 247     }
n 260     // Tried code: n
261     {
262         PyObject *tmp_assign_source_3;
263         PyObject *tmp_iter_arg_2;
264         CHECK_OBJECT(var_iterator);
265         tmp_iter_arg_2 = var_iterator;
266         tmp_assign_source_3 = MAKE_ITERATOR( tmp_iter_arg_2 );
267         if ( tmp_assign_source_3 == NULL )
268         {
269             assert(ERROR_OCCURRED());
270  
271             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
272  
273  
274             exception_lineno = 30;
275             type_description_1 = "oooo";
276             goto try_except_handler_2;
277         }
278         assert(tmp_tuple_unpack_1__source_iter == NULL);
279         tmp_tuple_unpack_1__source_iter = tmp_assign_source_3;
280     }
281     // Tried code:
282     {
283         PyObject *tmp_assign_source_4;
284         PyObject *tmp_unpack_1;
285         CHECK_OBJECT(tmp_tuple_unpack_1__source_iter);
286         tmp_unpack_1 = tmp_tuple_unpack_1__source_iter;
287         tmp_assign_source_4 = UNPACK_NEXT( tmp_unpack_1, 0, 2 );
288         if (tmp_assign_source_4 == NULL)
289         {
290             if (!ERROR_OCCURRED()) {
291                 exception_type = PyExc_StopIteration;
292                 Py_INCREF(exception_type);
293                 exception_value = NULL;
294                 exception_tb = NULL;
295             } else {
296                 FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
297             }
298  
299  
300             type_description_1 = "oooo";
301             exception_lineno = 30;
302             goto try_except_handler_3;
303         }
304         assert(tmp_tuple_unpack_1__element_1 == NULL);
305         tmp_tuple_unpack_1__element_1 = tmp_assign_source_4;
306     }
307     {
308         PyObject *tmp_assign_source_5;
309         PyObject *tmp_unpack_2;
310         CHECK_OBJECT(tmp_tuple_unpack_1__source_iter);
311         tmp_unpack_2 = tmp_tuple_unpack_1__source_iter;
312         tmp_assign_source_5 = UNPACK_NEXT( tmp_unpack_2, 1, 2 );
313         if (tmp_assign_source_5 == NULL)
314         {
315             if (!ERROR_OCCURRED()) {
316                 exception_type = PyExc_StopIteration;
317                 Py_INCREF(exception_type);
318                 exception_value = NULL;
319                 exception_tb = NULL;
320             } else {
321                 FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
322             }
323  
324  
325             type_description_1 = "oooo";
326             exception_lineno = 30;
327             goto try_except_handler_3;
328         }
329         assert(tmp_tuple_unpack_1__element_2 == NULL);
330         tmp_tuple_unpack_1__element_2 = tmp_assign_source_5;
331     }
332     {
333         PyObject *tmp_iterator_name_1;
334         CHECK_OBJECT(tmp_tuple_unpack_1__source_iter);
335         tmp_iterator_name_1 = tmp_tuple_unpack_1__source_iter;
336         // Check if iterator has left-over elements.
337         CHECK_OBJECT(tmp_iterator_name_1); assert(HAS_ITERNEXT(tmp_iterator_name_1));
338  
339         tmp_iterator_attempt = (*Py_TYPE(tmp_iterator_name_1)->tp_iternext)(tmp_iterator_name_1);
340  
341         if (likely(tmp_iterator_attempt == NULL))
342         {
343             PyObject *error = GET_ERROR_OCCURRED();
344  
345             if (error != NULL)
346             {
347                 if (EXCEPTION_MATCH_BOOL_SINGLE(error, PyExc_StopIteration))
348                 {
349                     CLEAR_ERROR_OCCURRED();
350                 } else {
351                     FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
352  
353                     type_description_1 = "oooo";
354                     exception_lineno = 30;
355                     goto try_except_handler_3;
356                 }
357             }
358         } else {
359             Py_DECREF(tmp_iterator_attempt);
360  
361             // TODO: Could avoid PyErr_Format.
362 #if PYTHON_VERSION < 300
363             PyErr_Format(PyExc_ValueError, "too many values to unpack");
364 #else
365             PyErr_Format(PyExc_ValueError, "too many values to unpack (expected 2)");
366 #endif
367             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
368  
369             type_description_1 = "oooo";
370             exception_lineno = 30;
371             goto try_except_handler_3;
372         }
373     }
374     goto try_end_1;
375     // Exception handler code:
376     try_except_handler_3:;
377     exception_keeper_type_1 = exception_type;
378     exception_keeper_value_1 = exception_value;
379     exception_keeper_tb_1 = exception_tb;
380     exception_keeper_lineno_1 = exception_lineno;
381     exception_type = NULL;
382     exception_value = NULL;
383     exception_tb = NULL;
384     exception_lineno = 0;
385  
386     CHECK_OBJECT((PyObject *)tmp_tuple_unpack_1__source_iter);
387     Py_DECREF(tmp_tuple_unpack_1__source_iter);
388     tmp_tuple_unpack_1__source_iter = NULL;
389  
390     // Re-raise.
391     exception_type = exception_keeper_type_1;
392     exception_value = exception_keeper_value_1;
393     exception_tb = exception_keeper_tb_1;
394     exception_lineno = exception_keeper_lineno_1;
395  
396     goto try_except_handler_2;
397     // End of try:
398     try_end_1:;
399     goto try_end_2;
400     // Exception handler code:
401     try_except_handler_2:;
402     exception_keeper_type_2 = exception_type;
403     exception_keeper_value_2 = exception_value;
404     exception_keeper_tb_2 = exception_tb;
405     exception_keeper_lineno_2 = exception_lineno;
406     exception_type = NULL;
407     exception_value = NULL;
408     exception_tb = NULL;
409     exception_lineno = 0;
410  
411     Py_XDECREF(tmp_tuple_unpack_1__element_1);
412     tmp_tuple_unpack_1__element_1 = NULL;
413  
414     Py_XDECREF(tmp_tuple_unpack_1__element_2);
415     tmp_tuple_unpack_1__element_2 = NULL;
416  
417     // Re-raise.
418     exception_type = exception_keeper_type_2;
419     exception_value = exception_keeper_value_2;
420     exception_tb = exception_keeper_tb_2;
421     exception_lineno = exception_keeper_lineno_2;
422  
423     goto frame_exception_exit_1;
424     // End of try:
425     try_end_2:;
426 248
427 #if 0 249 #if 0
428     RESTORE_FRAME_EXCEPTION(frame_93a53cae61099e6802731aa3f10e0532); 250     RESTORE_FRAME_EXCEPTION(frame_93a53cae61099e6802731aa3f10e0532);
429 #endif 251 #endif
430 252
470 292
471     // Return the error. 293     // Return the error.
472     goto try_except_handler_1; 294     goto try_except_handler_1;
473 295
474     frame_no_exception_1:; 296     frame_no_exception_1:;
n 475     CHECK_OBJECT((PyObject *)tmp_tuple_unpack_1__source_iter); n
476     Py_DECREF(tmp_tuple_unpack_1__source_iter);
477     tmp_tuple_unpack_1__source_iter = NULL;
478  
479     { 297     {
n 480         PyObject *tmp_assign_source_6; n 298         PyObject *tmp_assign_source_3;
481         CHECK_OBJECT(tmp_tuple_unpack_1__element_1); 299         CHECK_OBJECT(var_c);
482         tmp_assign_source_6 = tmp_tuple_unpack_1__element_1; 300         tmp_assign_source_3 = var_c;
483         assert(var_a == NULL); 301         assert(var_a == NULL);
n 484         Py_INCREF(tmp_assign_source_6); n 302         Py_INCREF(tmp_assign_source_3);
485         var_a = tmp_assign_source_6; 303         var_a = tmp_assign_source_3;
486     }
487     Py_XDECREF(tmp_tuple_unpack_1__element_1);
488     tmp_tuple_unpack_1__element_1 = NULL;
489  
490     { 304     }
305     {
491         PyObject *tmp_assign_source_7; 306         PyObject *tmp_assign_source_4;
492         CHECK_OBJECT(tmp_tuple_unpack_1__element_2); 307         CHECK_OBJECT(var_c);
493         tmp_assign_source_7 = tmp_tuple_unpack_1__element_2; 308         tmp_assign_source_4 = var_c;
494         assert(var_b == NULL); 309         assert(var_b == NULL);
n 495         Py_INCREF(tmp_assign_source_7); n 310         Py_INCREF(tmp_assign_source_4);
496         var_b = tmp_assign_source_7; 311         var_b = tmp_assign_source_4;
497     } 312     }
n 498     Py_XDECREF(tmp_tuple_unpack_1__element_2); n
499     tmp_tuple_unpack_1__element_2 = NULL;
500  
501     { 313     {
502         PyObject *tmp_tuple_element_1; 314         PyObject *tmp_tuple_element_1;
503         CHECK_OBJECT(var_a); 315         CHECK_OBJECT(var_a);
504         tmp_tuple_element_1 = var_a; 316         tmp_tuple_element_1 = var_a;
505         tmp_return_value = PyTuple_New( 2 ); 317         tmp_return_value = PyTuple_New( 2 );
533     var_iterator = NULL; 345     var_iterator = NULL;
534 346
535     goto function_return_exit; 347     goto function_return_exit;
536     // Exception handler code: 348     // Exception handler code:
537     try_except_handler_1:; 349     try_except_handler_1:;
n 538     exception_keeper_type_3 = exception_type; n 350     exception_keeper_type_1 = exception_type;
539     exception_keeper_value_3 = exception_value; 351     exception_keeper_value_1 = exception_value;
540     exception_keeper_tb_3 = exception_tb; 352     exception_keeper_tb_1 = exception_tb;
541     exception_keeper_lineno_3 = exception_lineno; 353     exception_keeper_lineno_1 = exception_lineno;
542     exception_type = NULL; 354     exception_type = NULL;
543     exception_value = NULL; 355     exception_value = NULL;
544     exception_tb = NULL; 356     exception_tb = NULL;
545     exception_lineno = 0; 357     exception_lineno = 0;
546 358
547     Py_XDECREF(var_c); 359     Py_XDECREF(var_c);
548     var_c = NULL; 360     var_c = NULL;
549 361
n 550     Py_XDECREF(var_iterator); n
551     var_iterator = NULL;
552  
553     // Re-raise. 362     // Re-raise.
t 554     exception_type = exception_keeper_type_3; t 363     exception_type = exception_keeper_type_1;
555     exception_value = exception_keeper_value_3; 364     exception_value = exception_keeper_value_1;
556     exception_tb = exception_keeper_tb_3; 365     exception_tb = exception_keeper_tb_1;
557     exception_lineno = exception_keeper_lineno_3; 366     exception_lineno = exception_keeper_lineno_1;
558 367
559     goto function_exception_exit; 368     goto function_exception_exit;
560     // End of try: 369     // End of try:
561 370
562     // Return statement must have exited already. 371     // Return statement must have exited already.