Construct GeneratorExpressionExit

Performance Diagrams

Construct GeneratorExpressionExit 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000280000000280000000300000000300000000CPython 2.7Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)31311278472.9230769230769257.0CPython 2.70194.46153846153845504.11538461538464Nuitka (historic)166003400316.0373.10190916922863Nuitka (master)160453933437.53846153846143377.4816686111663Nuitka (develop)160453909559.0769230769231377.48168755248565Nuitka (factory)Construct GeneratorExpressionExitTicks Construct GeneratorExpressionExit 0010000000100000002000000020000000300000003000000040000000400000005000000050000000600000006000000070000000700000008000000080000000CPython 3.5Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)8137075573.61538461538461257.0CPython 3.50196.30769230769232504.11538461538464Nuitka (historic)74454482319.0000000000001278.0040752663534Nuitka (master)67056431441.69230769230774300.4712653307596Nuitka (develop)67052643564.3846153846155300.48276913303994Nuitka (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


for x in xrange(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


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