Construct GeneratorExit

Performance Diagrams

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