Construct GeneratorExpressionExit

Performance Diagrams

Construct GeneratorExpressionExit 0040000000400000008000000080000000120000000120000000160000000160000000200000000200000000240000000240000000280000000280000000320000000320000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)34792858288.11538461538461257.0CPython 2.7164503024240.03846153846155387.27753297215907Nuitka (master)164503078391.96153846153845387.2774946187973Nuitka (develop)164503096543.8846153846154387.27748183434335Nuitka (factory)Construct GeneratorExpressionExitTicks Construct GeneratorExpressionExit 0010000000100000002000000020000000300000003000000040000000400000005000000050000000600000006000000070000000700000008000000080000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)8266849288.95192307692307257.0CPython 3.566203150242.31730769230768306.2187437162135Nuitka (master)66203364395.6826923076923306.21810402035084Nuitka (develop)66203634549.0480769230769306.21729692744Nuitka (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;
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_1 = "ooo"; n 257         type_description_1 = "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_1 = "ooo"; n 275         type_description_1 = "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_1 = "ooo"; n 288         type_description_1 = "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_9ccb71415e161e59c5e9c8d4fa5efa7f );
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_9ccb71415e161e59c5e9c8d4fa5efa7f->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_9ccb71415e161e59c5e9c8d4fa5efa7f );
308 #endif
309  
310     if ( exception_tb == NULL )
327     } 311     {
328   312         exception_tb = MAKE_TRACEBACK( frame_9ccb71415e161e59c5e9c8d4fa5efa7f, exception_lineno );
329     if ( tmp_unused == NULL )
330     { 313     }
331         assert( ERROR_OCCURRED() ); 314     else if ( exception_tb->tb_frame != &frame_9ccb71415e161e59c5e9c8d4fa5efa7f->m_frame )
315     {
316         exception_tb = ADD_TRACEBACK( exception_tb, frame_9ccb71415e161e59c5e9c8d4fa5efa7f, exception_lineno );
317     }
332 318
n 333         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb ); n 319     // Attachs locals to frame if any.
334   320     Nuitka_Frame_AttachLocals(
335   321         (struct Nuitka_FrameObject *)frame_9ccb71415e161e59c5e9c8d4fa5efa7f,
336         exception_lineno = 32;
337         type_description_1 = "ooo"; 322         type_description_1,
323         var_gen,
324         var_throw,
325         NULL
326     );
327  
328  
329     // Release cached frame.
330     if ( frame_9ccb71415e161e59c5e9c8d4fa5efa7f == cache_frame_9ccb71415e161e59c5e9c8d4fa5efa7f )
331     {
332         Py_DECREF( frame_9ccb71415e161e59c5e9c8d4fa5efa7f );
333     }
334     cache_frame_9ccb71415e161e59c5e9c8d4fa5efa7f = NULL;
335  
336     assertFrameObject( frame_9ccb71415e161e59c5e9c8d4fa5efa7f );
337  
338     // Put the previous frame back on top.
339     popFrameStack();
340  
341     // Return the error.
338         goto try_except_handler_3; 342     goto try_except_handler_2;
339     } 343  
340     Py_DECREF( tmp_unused ); 344     frame_no_exception_1:;
341     goto try_end_1; 345  
346     tmp_return_value = PyTuple_New( 2 );
347     tmp_tuple_element_1 = var_throw;
348  
349     CHECK_OBJECT( tmp_tuple_element_1 );
350     Py_INCREF( tmp_tuple_element_1 );
351     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
352     tmp_tuple_element_1 = PyExc_GeneratorExit;
353     Py_INCREF( tmp_tuple_element_1 );
354     PyTuple_SET_ITEM( tmp_return_value, 1, tmp_tuple_element_1 );
355     goto try_return_handler_2;
356     // tried codes exits in all cases
357     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
358     return NULL;
359     // Return handler code:
360     try_return_handler_2:;
361     Py_XDECREF( var_gen );
362     var_gen = NULL;
363  
364     Py_XDECREF( var_throw );
365     var_throw = NULL;
366  
367     goto function_return_exit;
342     // Exception handler code: 368     // Exception handler code:
n 343     try_except_handler_3:; n 369     try_except_handler_2:;
344     exception_keeper_type_1 = exception_type; 370     exception_keeper_type_1 = exception_type;
345     exception_keeper_value_1 = exception_value; 371     exception_keeper_value_1 = exception_value;
346     exception_keeper_tb_1 = exception_tb; 372     exception_keeper_tb_1 = exception_tb;
347     exception_keeper_lineno_1 = exception_lineno; 373     exception_keeper_lineno_1 = exception_lineno;
348     exception_type = NULL; 374     exception_type = NULL;
349     exception_value = NULL; 375     exception_value = NULL;
350     exception_tb = NULL; 376     exception_tb = NULL;
351     exception_lineno = 0; 377     exception_lineno = 0;
352 378
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_9ccb71415e161e59c5e9c8d4fa5efa7f, 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_9ccb71415e161e59c5e9c8d4fa5efa7f, 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_1 = "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_1 = "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_9ccb71415e161e59c5e9c8d4fa5efa7f->m_frame) frame_9ccb71415e161e59c5e9c8d4fa5efa7f->m_frame.f_lineno = exception_tb->tb_lineno;
420     type_description_1 = "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_1 = "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_1 = "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_9ccb71415e161e59c5e9c8d4fa5efa7f );
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_9ccb71415e161e59c5e9c8d4fa5efa7f );
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_9ccb71415e161e59c5e9c8d4fa5efa7f );
518 #endif
519  
520     if ( exception_tb == NULL )
521     {
522         exception_tb = MAKE_TRACEBACK( frame_9ccb71415e161e59c5e9c8d4fa5efa7f, exception_lineno );
523     }
524     else if ( exception_tb->tb_frame != &frame_9ccb71415e161e59c5e9c8d4fa5efa7f->m_frame )
525     {
526         exception_tb = ADD_TRACEBACK( exception_tb, frame_9ccb71415e161e59c5e9c8d4fa5efa7f, exception_lineno );
527     }
528  
529     // Attachs locals to frame if any.
530     Nuitka_Frame_AttachLocals(
531         (struct Nuitka_FrameObject *)frame_9ccb71415e161e59c5e9c8d4fa5efa7f,
532         type_description_1,
533         var_gen,
534         var_throw,
535         var_exc
536     );
537  
538  
539     // Release cached frame.
540     if ( frame_9ccb71415e161e59c5e9c8d4fa5efa7f == cache_frame_9ccb71415e161e59c5e9c8d4fa5efa7f )
541     {
542         Py_DECREF( frame_9ccb71415e161e59c5e9c8d4fa5efa7f );
543     }
544     cache_frame_9ccb71415e161e59c5e9c8d4fa5efa7f = NULL;
545  
546     assertFrameObject( frame_9ccb71415e161e59c5e9c8d4fa5efa7f );
547  
548     // Put the previous frame back on top.
549     popFrameStack();
550  
551     // Return the error.
552     goto try_except_handler_2;
553  
554     frame_no_exception_1:;
555  
556     // tried codes exits in all cases
557     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
558     return NULL;
559     // Return handler code:
560     try_return_handler_2:;
561     Py_XDECREF( var_gen ); 379     Py_XDECREF( var_gen );
562     var_gen = NULL; 380     var_gen = NULL;
563 381
n 564     Py_XDECREF( var_throw ); n
565     var_throw = NULL;
566  
567     Py_XDECREF( var_exc );
568     var_exc = NULL;
569  
570     goto function_return_exit;
571     // Exception handler code:
572     try_except_handler_2:;
573     exception_keeper_type_3 = exception_type;
574     exception_keeper_value_3 = exception_value;
575     exception_keeper_tb_3 = exception_tb;
576     exception_keeper_lineno_3 = exception_lineno;
577     exception_type = NULL;
578     exception_value = NULL;
579     exception_tb = NULL;
580     exception_lineno = 0;
581  
582     Py_XDECREF( var_gen );
583     var_gen = NULL;
584  
585     Py_XDECREF( var_throw );
586     var_throw = NULL;
587  
588     Py_XDECREF( var_exc );
589     var_exc = NULL;
590  
591     // Re-raise. 382     // Re-raise.
t 592     exception_type = exception_keeper_type_3; t 383     exception_type = exception_keeper_type_1;
593     exception_value = exception_keeper_value_3; 384     exception_value = exception_keeper_value_1;
594     exception_tb = exception_keeper_tb_3; 385     exception_tb = exception_keeper_tb_1;
595     exception_lineno = exception_keeper_lineno_3; 386     exception_lineno = exception_keeper_lineno_1;
596 387
597     goto function_exception_exit; 388     goto function_exception_exit;
598     // End of try: 389     // End of try:
599 390
600     // Return statement must have exited already. 391     // Return statement must have exited already.