Construct GeneratorExpressionExit

Performance Diagrams

Construct GeneratorExpressionExit 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000280000000280000000300000000300000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)31311274288.11538461538461257.0CPython 2.7162802789240.03846153846155375.6278833938843Nuitka (master)162752845391.96153846153845375.6673002847154Nuitka (develop)162752839543.8846153846154375.6673050200459Nuitka (factory)Construct GeneratorExpressionExitTicks Construct GeneratorExpressionExit 0010000000100000002000000020000000300000003000000040000000400000005000000050000000600000006000000070000000700000008000000080000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)8136913488.95192307692307257.0CPython 3.567149410242.31730769230768300.18483425649606Nuitka (master)67153246395.6826923076923300.1731844506202Nuitka (develop)67153380549.0480769230769300.172777497026Nuitka (factory)Construct GeneratorExpressionExitTicks

Source Code with Construct

def calledRepeatedly():
    # We measure making a generator iterator step or not.
    gen = (x for x in range(3))

    next(gen)

    # Take attribute lookup out of it, and built-in lookup too.
    throw = gen.throw
    exc = GeneratorExit

    try:
# construct_begin
        throw(exc)
# construct_alternative


    except exc:
        pass

    return throw, exc


import itertools
for x in itertools.repeat(None, 50000):
    calledRepeatedly()

print("OK.")

Source Code without Construct

def calledRepeatedly():
    # We measure making a generator iterator step or not.
    gen = (x for x in range(3))

    next(gen)

    # Take attribute lookup out of it, and built-in lookup too.
    throw = gen.throw
    exc = GeneratorExit

    try:
# construct_begin

# construct_alternative
        pass
# construct_end
    except exc:
        pass

    return throw, exc


import itertools
for x in itertools.repeat(None, 50000):
    calledRepeatedly()

print("OK.")

Context Diff of Source Code


Construct
Baseline
27     throw = gen.throw 27     throw = gen.throw
28     exc = GeneratorExit 28     exc = GeneratorExit
29 29
30     try: 30     try:
31 # construct_begin 31 # construct_begin
n 32         throw(exc) n 32  
33 # construct_alternative 33 # construct_alternative
t 34   t 34         pass
35   35 # construct_end
36     except exc: 36     except exc:
37         pass 37         pass
38 38
39     return throw, exc 39     return throw, exc
40 40

Context Diff of Generated Code


Construct
Baseline
148 #endif 148 #endif
149 149
150     // Local variable declarations. 150     // Local variable declarations.
151     PyObject *var_gen = NULL; 151     PyObject *var_gen = NULL;
152     PyObject *var_throw = NULL; 152     PyObject *var_throw = NULL;
n 153     PyObject *var_exc = NULL; n
154     PyObject *tmp_genexpr_1__$0 = NULL; 153     PyObject *tmp_genexpr_1__$0 = NULL;
155     PyObject *exception_type = NULL; 154     PyObject *exception_type = NULL;
156     PyObject *exception_value = NULL; 155     PyObject *exception_value = NULL;
157     PyTracebackObject *exception_tb = NULL; 156     PyTracebackObject *exception_tb = NULL;
158     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 157     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
159     PyObject *exception_keeper_type_1; 158     PyObject *exception_keeper_type_1;
160     PyObject *exception_keeper_value_1; 159     PyObject *exception_keeper_value_1;
161     PyTracebackObject *exception_keeper_tb_1; 160     PyTracebackObject *exception_keeper_tb_1;
162     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 161     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
n 163     PyObject *exception_keeper_type_2; n
164     PyObject *exception_keeper_value_2;
165     PyTracebackObject *exception_keeper_tb_2;
166     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_2;
167     PyObject *exception_keeper_type_3;
168     PyObject *exception_keeper_value_3;
169     PyTracebackObject *exception_keeper_tb_3;
170     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
171     PyObject *exception_preserved_type_1;
172     PyObject *exception_preserved_value_1;
173     PyTracebackObject *exception_preserved_tb_1;
174     PyObject *tmp_args_element_name_1;
175     PyObject *tmp_assign_source_1; 162     PyObject *tmp_assign_source_1;
176     PyObject *tmp_assign_source_2; 163     PyObject *tmp_assign_source_2;
177     PyObject *tmp_assign_source_3; 164     PyObject *tmp_assign_source_3;
n 178     PyObject *tmp_assign_source_4; n
179     PyObject *tmp_called_name_1;
180     PyObject *tmp_compare_left_1;
181     PyObject *tmp_compare_right_1;
182     int tmp_exc_match_exception_match_1;
183     PyObject *tmp_iter_arg_1; 165     PyObject *tmp_iter_arg_1;
184     PyObject *tmp_outline_return_value_1; 166     PyObject *tmp_outline_return_value_1;
n 185     bool tmp_result; n
186     PyObject *tmp_return_value; 167     PyObject *tmp_return_value;
187     PyObject *tmp_source_name_1; 168     PyObject *tmp_source_name_1;
188     PyObject *tmp_tuple_element_1; 169     PyObject *tmp_tuple_element_1;
189     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused; 170     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused;
190     PyObject *tmp_value_name_1; 171     PyObject *tmp_value_name_1;
242     tmp_assign_source_1 = tmp_outline_return_value_1; 223     tmp_assign_source_1 = tmp_outline_return_value_1;
243     assert( var_gen == NULL ); 224     assert( var_gen == NULL );
244     var_gen = tmp_assign_source_1; 225     var_gen = tmp_assign_source_1;
245 226
246     // Tried code: 227     // Tried code:
n 247     MAKE_OR_REUSE_FRAME( cache_frame_6e7bcd039f79f2b9746ec056861344f9, codeobj_6e7bcd039f79f2b9746ec056861344f9, module___main__, sizeof(PyObject *)+sizeof(PyObject *)+sizeof(PyObject *) ); n 228     MAKE_OR_REUSE_FRAME( cache_frame_6e7bcd039f79f2b9746ec056861344f9, codeobj_6e7bcd039f79f2b9746ec056861344f9, module___main__, sizeof(void *)+sizeof(PyObject *)+sizeof(PyObject *) );
248     frame_6e7bcd039f79f2b9746ec056861344f9 = cache_frame_6e7bcd039f79f2b9746ec056861344f9; 229     frame_6e7bcd039f79f2b9746ec056861344f9 = cache_frame_6e7bcd039f79f2b9746ec056861344f9;
249 230
250     // Push the new frame as the currently active one. 231     // Push the new frame as the currently active one.
251     pushFrameStack( frame_6e7bcd039f79f2b9746ec056861344f9 ); 232     pushFrameStack( frame_6e7bcd039f79f2b9746ec056861344f9 );
252 233
271         { 252         {
272             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb ); 253             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
273         } 254         }
274 255
275 256
n 276         type_description = "ooo"; n 257         type_description = "ooN";
277         exception_lineno = 24; 258         exception_lineno = 24;
278         goto frame_exception_exit_1; 259         goto frame_exception_exit_1;
279     } 260     }
280     Py_DECREF( tmp_unused ); 261     Py_DECREF( tmp_unused );
281     tmp_source_name_1 = var_gen; 262     tmp_source_name_1 = var_gen;
289         exception_tb = NULL; 270         exception_tb = NULL;
290         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb ); 271         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
291         CHAIN_EXCEPTION( exception_value ); 272         CHAIN_EXCEPTION( exception_value );
292 273
293         exception_lineno = 27; 274         exception_lineno = 27;
n 294         type_description = "ooo"; n 275         type_description = "ooN";
295         goto frame_exception_exit_1; 276         goto frame_exception_exit_1;
296     } 277     }
297 278
298     tmp_assign_source_3 = LOOKUP_ATTRIBUTE( tmp_source_name_1, const_str_plain_throw ); 279     tmp_assign_source_3 = LOOKUP_ATTRIBUTE( tmp_source_name_1, const_str_plain_throw );
299     if ( tmp_assign_source_3 == NULL ) 280     if ( tmp_assign_source_3 == NULL )
302 283
303         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb ); 284         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
304 285
305 286
306         exception_lineno = 27; 287         exception_lineno = 27;
n 307         type_description = "ooo"; n 288         type_description = "ooN";
308         goto frame_exception_exit_1; 289         goto frame_exception_exit_1;
309     } 290     }
310     assert( var_throw == NULL ); 291     assert( var_throw == NULL );
311     var_throw = tmp_assign_source_3; 292     var_throw = tmp_assign_source_3;
312 293
n 313     tmp_assign_source_4 = PyExc_GeneratorExit; n
314     assert( var_exc == NULL );
315     Py_INCREF( tmp_assign_source_4 );
316     var_exc = tmp_assign_source_4;
317 294
n 318     // Tried code: n 295 #if 0
319     tmp_called_name_1 = var_throw; 296     RESTORE_FRAME_EXCEPTION( frame_6e7bcd039f79f2b9746ec056861344f9 );
297 #endif
320 298
n 321     CHECK_OBJECT( tmp_called_name_1 ); n 299     // Put the previous frame back on top.
322     tmp_args_element_name_1 = PyExc_GeneratorExit; 300     popFrameStack();
323     frame_6e7bcd039f79f2b9746ec056861344f9->m_frame.f_lineno = 32; 301  
324     { 302     goto frame_no_exception_1;
325         PyObject *call_args[] = { tmp_args_element_name_1 }; 303  
326         tmp_unused = CALL_FUNCTION_WITH_ARGS1( tmp_called_name_1, call_args ); 304     frame_exception_exit_1:;
305  
306 #if 0
307     RESTORE_FRAME_EXCEPTION( frame_6e7bcd039f79f2b9746ec056861344f9 );
308 #endif
309  
310     if ( exception_tb == NULL )
327     } 311     {
328   312         exception_tb = MAKE_TRACEBACK( frame_6e7bcd039f79f2b9746ec056861344f9, exception_lineno );
329     if ( tmp_unused == NULL )
330     { 313     }
331         assert( ERROR_OCCURRED() ); 314     else if ( exception_tb->tb_frame != &frame_6e7bcd039f79f2b9746ec056861344f9->m_frame )
315     {
316         exception_tb = ADD_TRACEBACK( exception_tb, frame_6e7bcd039f79f2b9746ec056861344f9, exception_lineno );
317     }
332 318
n 333         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb ); n 319     Nuitka_Frame_AttachLocals( (struct Nuitka_FrameObject *)frame_6e7bcd039f79f2b9746ec056861344f9, type_description ,var_gen, var_throw, NULL );
334 320
n n 321     // Release cached frame.
322     if ( frame_6e7bcd039f79f2b9746ec056861344f9 == cache_frame_6e7bcd039f79f2b9746ec056861344f9 )
323     {
324         Py_DECREF( frame_6e7bcd039f79f2b9746ec056861344f9 );
325     }
326     cache_frame_6e7bcd039f79f2b9746ec056861344f9 = NULL;
335 327
n 336         exception_lineno = 32; n 328     assertFrameObject( frame_6e7bcd039f79f2b9746ec056861344f9 );
337         type_description = "ooo"; 329  
330  
331     // Put the previous frame back on top.
332     popFrameStack();
333  
334     // Return the error.
338         goto try_except_handler_3; 335     goto try_except_handler_2;
339     } 336  
340     Py_DECREF( tmp_unused ); 337     frame_no_exception_1:;
341     goto try_end_1; 338  
339     tmp_return_value = PyTuple_New( 2 );
340     tmp_tuple_element_1 = var_throw;
341  
342     CHECK_OBJECT( tmp_tuple_element_1 );
343     Py_INCREF( tmp_tuple_element_1 );
344     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
345     tmp_tuple_element_1 = PyExc_GeneratorExit;
346     Py_INCREF( tmp_tuple_element_1 );
347     PyTuple_SET_ITEM( tmp_return_value, 1, tmp_tuple_element_1 );
348     goto try_return_handler_2;
349     // tried codes exits in all cases
350     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
351     return NULL;
352     // Return handler code:
353     try_return_handler_2:;
354     Py_XDECREF( var_gen );
355     var_gen = NULL;
356  
357     Py_XDECREF( var_throw );
358     var_throw = NULL;
359  
360     goto function_return_exit;
342     // Exception handler code: 361     // Exception handler code:
n 343     try_except_handler_3:; n 362     try_except_handler_2:;
344     exception_keeper_type_1 = exception_type; 363     exception_keeper_type_1 = exception_type;
345     exception_keeper_value_1 = exception_value; 364     exception_keeper_value_1 = exception_value;
346     exception_keeper_tb_1 = exception_tb; 365     exception_keeper_tb_1 = exception_tb;
347     exception_keeper_lineno_1 = exception_lineno; 366     exception_keeper_lineno_1 = exception_lineno;
348     exception_type = NULL; 367     exception_type = NULL;
349     exception_value = NULL; 368     exception_value = NULL;
350     exception_tb = NULL; 369     exception_tb = NULL;
351     exception_lineno = 0; 370     exception_lineno = 0;
352 371
n 353     // Preserve existing published exception. n
354     exception_preserved_type_1 = PyThreadState_GET()->exc_type;
355     Py_XINCREF( exception_preserved_type_1 );
356     exception_preserved_value_1 = PyThreadState_GET()->exc_value;
357     Py_XINCREF( exception_preserved_value_1 );
358     exception_preserved_tb_1 = (PyTracebackObject *)PyThreadState_GET()->exc_traceback;
359     Py_XINCREF( exception_preserved_tb_1 );
360  
361     if ( exception_keeper_tb_1 == NULL )
362     {
363         exception_keeper_tb_1 = MAKE_TRACEBACK( frame_6e7bcd039f79f2b9746ec056861344f9, exception_keeper_lineno_1 );
364     }
365     else if ( exception_keeper_lineno_1 != 0 )
366     {
367         exception_keeper_tb_1 = ADD_TRACEBACK( exception_keeper_tb_1, frame_6e7bcd039f79f2b9746ec056861344f9, exception_keeper_lineno_1 );
368     }
369  
370     NORMALIZE_EXCEPTION( &exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1 );
371     PyException_SetTraceback( exception_keeper_value_1, (PyObject *)exception_keeper_tb_1 );
372     PUBLISH_EXCEPTION( &exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1 );
373     // Tried code:
374     tmp_compare_left_1 = PyThreadState_GET()->exc_type;
375     tmp_compare_right_1 = var_exc;
376  
377     if ( tmp_compare_right_1 == NULL )
378     {
379  
380         exception_type = PyExc_UnboundLocalError;
381         Py_INCREF( exception_type );
382         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "exc" );
383         exception_tb = NULL;
384         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
385         CHAIN_EXCEPTION( exception_value );
386  
387         exception_lineno = 36;
388         type_description = "ooo";
389         goto try_except_handler_4;
390     }
391  
392     tmp_exc_match_exception_match_1 = EXCEPTION_MATCH_BOOL( tmp_compare_left_1, tmp_compare_right_1 );
393     if ( tmp_exc_match_exception_match_1 == -1 )
394     {
395         assert( ERROR_OCCURRED() );
396  
397         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
398  
399  
400         exception_lineno = 36;
401         type_description = "ooo";
402         goto try_except_handler_4;
403     }
404     if ( tmp_exc_match_exception_match_1 == 1 )
405     {
406         goto branch_no_1;
407     }
408     else
409     {
410         goto branch_yes_1;
411     }
412     branch_yes_1:;
413     tmp_result = RERAISE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
414     if (unlikely( tmp_result == false ))
415     {
416         exception_lineno = 30;
417     }
418  
419     if (exception_tb && exception_tb->tb_frame == &frame_6e7bcd039f79f2b9746ec056861344f9->m_frame) frame_6e7bcd039f79f2b9746ec056861344f9->m_frame.f_lineno = exception_tb->tb_lineno;
420     type_description = "ooo";
421     goto try_except_handler_4;
422     branch_no_1:;
423     goto try_end_2;
424     // Exception handler code:
425     try_except_handler_4:;
426     exception_keeper_type_2 = exception_type;
427     exception_keeper_value_2 = exception_value;
428     exception_keeper_tb_2 = exception_tb;
429     exception_keeper_lineno_2 = exception_lineno;
430     exception_type = NULL;
431     exception_value = NULL;
432     exception_tb = NULL;
433     exception_lineno = 0;
434  
435     // Restore previous exception.
436     SET_CURRENT_EXCEPTION( exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1 );
437     // Re-raise.
438     exception_type = exception_keeper_type_2;
439     exception_value = exception_keeper_value_2;
440     exception_tb = exception_keeper_tb_2;
441     exception_lineno = exception_keeper_lineno_2;
442  
443     goto frame_exception_exit_1;
444     // End of try:
445     try_end_2:;
446     // Restore previous exception.
447     SET_CURRENT_EXCEPTION( exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1 );
448     goto try_end_1;
449     // exception handler codes exits in all cases
450     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
451     return NULL;
452     // End of try:
453     try_end_1:;
454     tmp_return_value = PyTuple_New( 2 );
455     tmp_tuple_element_1 = var_throw;
456  
457     if ( tmp_tuple_element_1 == NULL )
458     {
459         Py_DECREF( tmp_return_value );
460         exception_type = PyExc_UnboundLocalError;
461         Py_INCREF( exception_type );
462         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "throw" );
463         exception_tb = NULL;
464         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
465         CHAIN_EXCEPTION( exception_value );
466  
467         exception_lineno = 39;
468         type_description = "ooo";
469         goto frame_exception_exit_1;
470     }
471  
472     Py_INCREF( tmp_tuple_element_1 );
473     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
474     tmp_tuple_element_1 = var_exc;
475  
476     if ( tmp_tuple_element_1 == NULL )
477     {
478         Py_DECREF( tmp_return_value );
479         exception_type = PyExc_UnboundLocalError;
480         Py_INCREF( exception_type );
481         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "exc" );
482         exception_tb = NULL;
483         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
484         CHAIN_EXCEPTION( exception_value );
485  
486         exception_lineno = 39;
487         type_description = "ooo";
488         goto frame_exception_exit_1;
489     }
490  
491     Py_INCREF( tmp_tuple_element_1 );
492     PyTuple_SET_ITEM( tmp_return_value, 1, tmp_tuple_element_1 );
493     goto frame_return_exit_1;
494  
495 #if 1
496     RESTORE_FRAME_EXCEPTION( frame_6e7bcd039f79f2b9746ec056861344f9 );
497 #endif
498  
499     // Put the previous frame back on top.
500     popFrameStack();
501  
502     goto frame_no_exception_1;
503  
504     frame_return_exit_1:;
505 #if 1
506     RESTORE_FRAME_EXCEPTION( frame_6e7bcd039f79f2b9746ec056861344f9 );
507 #endif
508  
509     // Put the previous frame back on top.
510     popFrameStack();
511  
512     goto try_return_handler_2;
513  
514     frame_exception_exit_1:;
515  
516 #if 1
517     RESTORE_FRAME_EXCEPTION( frame_6e7bcd039f79f2b9746ec056861344f9 );
518 #endif
519  
520     if ( exception_tb == NULL )
521     {
522         exception_tb = MAKE_TRACEBACK( frame_6e7bcd039f79f2b9746ec056861344f9, exception_lineno );
523     }
524     else if ( exception_tb->tb_frame != &frame_6e7bcd039f79f2b9746ec056861344f9->m_frame )
525     {
526         exception_tb = ADD_TRACEBACK( exception_tb, frame_6e7bcd039f79f2b9746ec056861344f9, exception_lineno );
527     }
528  
529     Nuitka_Frame_AttachLocals( (struct Nuitka_FrameObject *)frame_6e7bcd039f79f2b9746ec056861344f9, type_description ,var_gen, var_throw, var_exc );
530  
531     // Release cached frame.
532     if ( frame_6e7bcd039f79f2b9746ec056861344f9 == cache_frame_6e7bcd039f79f2b9746ec056861344f9 )
533     {
534         Py_DECREF( frame_6e7bcd039f79f2b9746ec056861344f9 );
535     }
536     cache_frame_6e7bcd039f79f2b9746ec056861344f9 = NULL;
537  
538     assertFrameObject( frame_6e7bcd039f79f2b9746ec056861344f9 );
539  
540  
541     // Put the previous frame back on top.
542     popFrameStack();
543  
544     // Return the error.
545     goto try_except_handler_2;
546  
547     frame_no_exception_1:;
548  
549     // tried codes exits in all cases
550     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
551     return NULL;
552     // Return handler code:
553     try_return_handler_2:;
554     Py_XDECREF( var_gen ); 372     Py_XDECREF( var_gen );
555     var_gen = NULL; 373     var_gen = NULL;
556 374
n 557     Py_XDECREF( var_throw ); n
558     var_throw = NULL;
559  
560     Py_XDECREF( var_exc );
561     var_exc = NULL;
562  
563     goto function_return_exit;
564     // Exception handler code:
565     try_except_handler_2:;
566     exception_keeper_type_3 = exception_type;
567     exception_keeper_value_3 = exception_value;
568     exception_keeper_tb_3 = exception_tb;
569     exception_keeper_lineno_3 = exception_lineno;
570     exception_type = NULL;
571     exception_value = NULL;
572     exception_tb = NULL;
573     exception_lineno = 0;
574  
575     Py_XDECREF( var_gen );
576     var_gen = NULL;
577  
578     Py_XDECREF( var_throw );
579     var_throw = NULL;
580  
581     Py_XDECREF( var_exc );
582     var_exc = NULL;
583  
584     // Re-raise. 375     // Re-raise.
t 585     exception_type = exception_keeper_type_3; t 376     exception_type = exception_keeper_type_1;
586     exception_value = exception_keeper_value_3; 377     exception_value = exception_keeper_value_1;
587     exception_tb = exception_keeper_tb_3; 378     exception_tb = exception_keeper_tb_1;
588     exception_lineno = exception_keeper_lineno_3; 379     exception_lineno = exception_keeper_lineno_1;
589 380
590     goto function_exception_exit; 381     goto function_exception_exit;
591     // End of try: 382     // End of try:
592 383
593     // Return statement must have exited already. 384     // Return statement must have exited already.