Construct GeneratorExit

Performance Diagrams

Construct GeneratorExit 0040000000400000008000000080000000120000000120000000160000000160000000200000000200000000240000000240000000280000000280000000320000000320000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)34662635988.11538461538461257.0CPython 2.7163503289240.03846153846155387.5513175788227Nuitka (master)163504616391.96153846153845387.5503715396457Nuitka (develop)163504922543.8846153846154387.5501533874316Nuitka (factory)Construct GeneratorExitTicks Construct GeneratorExit 0010000000100000002000000020000000300000003000000040000000400000005000000050000000600000006000000070000000700000008000000080000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)8331869388.95192307692307257.0CPython 3.566053453242.31730769230768308.2070733403958Nuitka (master)66053557395.6826923076923308.20676488620535Nuitka (develop)66053435549.0480769230769308.207126726698Nuitka (factory)Construct GeneratorExitTicks

Source Code with Construct

def calledRepeatedly():
    # We measure making a generator iterator step or not.
    def generator():
        yield 1
        yield 2
        yield 3

    gen = generator()

    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.
    def generator():
        yield 1
        yield 2
        yield 3

    gen = generator()

    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
32     throw = gen.throw 32     throw = gen.throw
33     exc = GeneratorExit 33     exc = GeneratorExit
34 34
35     try: 35     try:
36 # construct_begin 36 # construct_begin
n 37         throw(exc) n 37  
38 # construct_alternative 38 # construct_alternative
t 39   t 39         pass
40   40 # construct_end
41     except exc: 41     except exc:
42         pass 42         pass
43 43
44     return throw, exc 44     return throw, exc
45 45

Context Diff of Generated Code


Construct
Baseline
54 static PyObject *const_str_plain_generator; 54 static PyObject *const_str_plain_generator;
55 static PyObject *const_str_plain_repeat; 55 static PyObject *const_str_plain_repeat;
56 static PyObject *const_int_pos_2; 56 static PyObject *const_int_pos_2;
57 static PyObject *const_tuple_none_int_pos_50000_tuple; 57 static PyObject *const_tuple_none_int_pos_50000_tuple;
58 extern PyObject *const_str_plain___main__; 58 extern PyObject *const_str_plain___main__;
n 59 static PyObject *const_tuple_type_GeneratorExit_tuple; n
60 extern PyObject *const_str_plain___doc__; 59 extern PyObject *const_str_plain___doc__;
61 extern PyObject *const_str_plain___cached__; 60 extern PyObject *const_str_plain___cached__;
62 static PyObject *module_filename_obj; 61 static PyObject *module_filename_obj;
63 62
64 /* Indicator if this modules private constants were created yet. */ 63 /* Indicator if this modules private constants were created yet. */
90     const_str_plain_repeat = UNSTREAM_STRING_ASCII( &constant_bin[ 138 ], 6, 1 ); 89     const_str_plain_repeat = UNSTREAM_STRING_ASCII( &constant_bin[ 138 ], 6, 1 );
91     const_int_pos_2 = PyLong_FromUnsignedLong( 2ul ); 90     const_int_pos_2 = PyLong_FromUnsignedLong( 2ul );
92     const_tuple_none_int_pos_50000_tuple = PyTuple_New( 2 ); 91     const_tuple_none_int_pos_50000_tuple = PyTuple_New( 2 );
93     PyTuple_SET_ITEM( const_tuple_none_int_pos_50000_tuple, 0, Py_None ); Py_INCREF( Py_None ); 92     PyTuple_SET_ITEM( const_tuple_none_int_pos_50000_tuple, 0, Py_None ); Py_INCREF( Py_None );
94     PyTuple_SET_ITEM( const_tuple_none_int_pos_50000_tuple, 1, const_int_pos_50000 ); Py_INCREF( const_int_pos_50000 ); 93     PyTuple_SET_ITEM( const_tuple_none_int_pos_50000_tuple, 1, const_int_pos_50000 ); Py_INCREF( const_int_pos_50000 );
n 95     const_tuple_type_GeneratorExit_tuple = PyTuple_New( 1 ); n
96     PyTuple_SET_ITEM( const_tuple_type_GeneratorExit_tuple, 0, (PyObject *)PyExc_GeneratorExit ); Py_INCREF( (PyObject *)PyExc_GeneratorExit );
97 94
98     constants_created = true; 95     constants_created = true;
99 } 96 }
100 97
101 /* Function to verify module private constants for non-corruption. */ 98 /* Function to verify module private constants for non-corruption. */
150     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL; 147     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
151     PyObject *exception_type = NULL; 148     PyObject *exception_type = NULL;
152     PyObject *exception_value = NULL; 149     PyObject *exception_value = NULL;
153     PyTracebackObject *exception_tb = NULL; 150     PyTracebackObject *exception_tb = NULL;
154     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 151     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
n n 152     static struct Nuitka_FrameObject *cache_frame_9f6143dc0dcbf3846fb084135019b2bf = NULL;
153     PyObject *tmp_return_value = NULL;
155     PyObject *exception_keeper_type_1; 154     PyObject *exception_keeper_type_1;
156     PyObject *exception_keeper_value_1; 155     PyObject *exception_keeper_value_1;
157     PyTracebackObject *exception_keeper_tb_1; 156     PyTracebackObject *exception_keeper_tb_1;
158     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 157     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
n 159     PyObject *exception_preserved_type_1; n
160     PyObject *exception_preserved_value_1;
161     PyTracebackObject *exception_preserved_tb_1;
162     int tmp_res;
163     bool tmp_result;
164     PyObject *exception_keeper_type_2;
165     PyObject *exception_keeper_value_2;
166     PyTracebackObject *exception_keeper_tb_2;
167     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_2;
168     static struct Nuitka_FrameObject *cache_frame_9f6143dc0dcbf3846fb084135019b2bf = NULL;
169     PyObject *tmp_return_value = NULL;
170     PyObject *exception_keeper_type_3;
171     PyObject *exception_keeper_value_3;
172     PyTracebackObject *exception_keeper_tb_3;
173     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
174 158
175     // Actual function body. 159     // Actual function body.
176     { 160     {
177         PyObject *tmp_assign_source_1; 161         PyObject *tmp_assign_source_1;
178         tmp_assign_source_1 = MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_generator(  ); 162         tmp_assign_source_1 = MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_generator(  );
259             goto frame_exception_exit_1; 243             goto frame_exception_exit_1;
260         } 244         }
261         assert( var_throw == NULL ); 245         assert( var_throw == NULL );
262         var_throw = tmp_assign_source_3; 246         var_throw = tmp_assign_source_3;
263     } 247     }
n 264     // Tried code: n
265     {
266         PyObject *tmp_called_name_2;
267         PyObject *tmp_call_result_1;
268         CHECK_OBJECT( var_throw );
269         tmp_called_name_2 = var_throw;
270         frame_9f6143dc0dcbf3846fb084135019b2bf->m_frame.f_lineno = 37;
271         tmp_call_result_1 = CALL_FUNCTION_WITH_ARGS1( tmp_called_name_2, &PyTuple_GET_ITEM( const_tuple_type_GeneratorExit_tuple, 0 ) );
272  
273         if ( tmp_call_result_1 == NULL )
274         {
275             assert( ERROR_OCCURRED() );
276  
277             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
278  
279  
280             exception_lineno = 37;
281             type_description_1 = "oNoo";
282             goto try_except_handler_2;
283         }
284         Py_DECREF( tmp_call_result_1 );
285     }
286     goto try_end_1;
287     // Exception handler code:
288     try_except_handler_2:;
289     exception_keeper_type_1 = exception_type;
290     exception_keeper_value_1 = exception_value;
291     exception_keeper_tb_1 = exception_tb;
292     exception_keeper_lineno_1 = exception_lineno;
293     exception_type = NULL;
294     exception_value = NULL;
295     exception_tb = NULL;
296     exception_lineno = 0;
297  
298     // Preserve existing published exception.
299     exception_preserved_type_1 = EXC_TYPE(PyThreadState_GET());
300     Py_XINCREF( exception_preserved_type_1 );
301     exception_preserved_value_1 = EXC_VALUE(PyThreadState_GET());
302     Py_XINCREF( exception_preserved_value_1 );
303     exception_preserved_tb_1 = (PyTracebackObject *)EXC_TRACEBACK(PyThreadState_GET());
304     Py_XINCREF( exception_preserved_tb_1 );
305  
306     if ( exception_keeper_tb_1 == NULL )
307     {
308         exception_keeper_tb_1 = MAKE_TRACEBACK( frame_9f6143dc0dcbf3846fb084135019b2bf, exception_keeper_lineno_1 );
309     }
310     else if ( exception_keeper_lineno_1 != 0 )
311     {
312         exception_keeper_tb_1 = ADD_TRACEBACK( exception_keeper_tb_1, frame_9f6143dc0dcbf3846fb084135019b2bf, exception_keeper_lineno_1 );
313     }
314  
315     NORMALIZE_EXCEPTION( &exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1 );
316     PyException_SetTraceback( exception_keeper_value_1, (PyObject *)exception_keeper_tb_1 );
317     PUBLISH_EXCEPTION( &exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1 );
318     // Tried code:
319     {
320         nuitka_bool tmp_condition_result_1;
321         PyObject *tmp_operand_name_1;
322         PyObject *tmp_compexpr_left_1;
323         PyObject *tmp_compexpr_right_1;
324         tmp_compexpr_left_1 = EXC_TYPE(PyThreadState_GET());
325         tmp_compexpr_right_1 = PyExc_GeneratorExit;
326         tmp_res = EXCEPTION_MATCH_BOOL( tmp_compexpr_left_1, tmp_compexpr_right_1 );
327         if ( tmp_res == -1 )
328         {
329             assert( ERROR_OCCURRED() );
330  
331             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
332  
333  
334             exception_lineno = 41;
335             type_description_1 = "oNoo";
336             goto try_except_handler_3;
337         }
338         tmp_operand_name_1 = ( tmp_res != 0 ) ? Py_True : Py_False;
339         tmp_res = CHECK_IF_TRUE( tmp_operand_name_1 );
340         if ( tmp_res == -1 )
341         {
342             assert( ERROR_OCCURRED() );
343  
344             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
345  
346  
347             exception_lineno = 41;
348             type_description_1 = "oNoo";
349             goto try_except_handler_3;
350         }
351         tmp_condition_result_1 = ( tmp_res == 0 ) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
352         if ( tmp_condition_result_1 == NUITKA_BOOL_TRUE )
353         {
354             goto branch_yes_1;
355         }
356         else
357         {
358             goto branch_no_1;
359         }
360         branch_yes_1:;
361         tmp_result = RERAISE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
362         if (unlikely( tmp_result == false ))
363         {
364             exception_lineno = 35;
365         }
366  
367         if (exception_tb && exception_tb->tb_frame == &frame_9f6143dc0dcbf3846fb084135019b2bf->m_frame) frame_9f6143dc0dcbf3846fb084135019b2bf->m_frame.f_lineno = exception_tb->tb_lineno;
368         type_description_1 = "oNoo";
369         goto try_except_handler_3;
370         branch_no_1:;
371     }
372     goto try_end_2;
373     // Exception handler code:
374     try_except_handler_3:;
375     exception_keeper_type_2 = exception_type;
376     exception_keeper_value_2 = exception_value;
377     exception_keeper_tb_2 = exception_tb;
378     exception_keeper_lineno_2 = exception_lineno;
379     exception_type = NULL;
380     exception_value = NULL;
381     exception_tb = NULL;
382     exception_lineno = 0;
383  
384     // Restore previous exception.
385     SET_CURRENT_EXCEPTION( exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1 );
386     // Re-raise.
387     exception_type = exception_keeper_type_2;
388     exception_value = exception_keeper_value_2;
389     exception_tb = exception_keeper_tb_2;
390     exception_lineno = exception_keeper_lineno_2;
391  
392     goto frame_exception_exit_1;
393     // End of try:
394     try_end_2:;
395     // Restore previous exception.
396     SET_CURRENT_EXCEPTION( exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1 );
397     goto try_end_1;
398     // exception handler codes exits in all cases
399     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
400     return NULL;
401     // End of try:
402     try_end_1:;
403 248
404 #if 0 249 #if 0
405     RESTORE_FRAME_EXCEPTION( frame_9f6143dc0dcbf3846fb084135019b2bf ); 250     RESTORE_FRAME_EXCEPTION( frame_9f6143dc0dcbf3846fb084135019b2bf );
406 #endif 251 #endif
407 252
482     var_generator = NULL; 327     var_generator = NULL;
483 328
484     goto function_return_exit; 329     goto function_return_exit;
485     // Exception handler code: 330     // Exception handler code:
486     try_except_handler_1:; 331     try_except_handler_1:;
n 487     exception_keeper_type_3 = exception_type; n 332     exception_keeper_type_1 = exception_type;
488     exception_keeper_value_3 = exception_value; 333     exception_keeper_value_1 = exception_value;
489     exception_keeper_tb_3 = exception_tb; 334     exception_keeper_tb_1 = exception_tb;
490     exception_keeper_lineno_3 = exception_lineno; 335     exception_keeper_lineno_1 = exception_lineno;
491     exception_type = NULL; 336     exception_type = NULL;
492     exception_value = NULL; 337     exception_value = NULL;
493     exception_tb = NULL; 338     exception_tb = NULL;
494     exception_lineno = 0; 339     exception_lineno = 0;
495 340
496     Py_XDECREF( var_gen ); 341     Py_XDECREF( var_gen );
497     var_gen = NULL; 342     var_gen = NULL;
498 343
n 499     Py_XDECREF( var_throw ); n
500     var_throw = NULL;
501  
502     CHECK_OBJECT( (PyObject *)var_generator ); 344     CHECK_OBJECT( (PyObject *)var_generator );
503     Py_DECREF( var_generator ); 345     Py_DECREF( var_generator );
504     var_generator = NULL; 346     var_generator = NULL;
505 347
506     // Re-raise. 348     // Re-raise.
t 507     exception_type = exception_keeper_type_3; t 349     exception_type = exception_keeper_type_1;
508     exception_value = exception_keeper_value_3; 350     exception_value = exception_keeper_value_1;
509     exception_tb = exception_keeper_tb_3; 351     exception_tb = exception_keeper_tb_1;
510     exception_lineno = exception_keeper_lineno_3; 352     exception_lineno = exception_keeper_lineno_1;
511 353
512     goto function_exception_exit; 354     goto function_exception_exit;
513     // End of try: 355     // End of try:
514 356
515     // Return statement must have exited already. 357     // Return statement must have exited already.