Construct GeneratorExit

Performance Diagrams

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