Construct GeneratorExit

Performance Diagrams

Construct GeneratorExit 0040000000400000008000000080000000120000000120000000160000000160000000200000000200000000240000000240000000280000000280000000320000000320000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)33366988288.11538461538461257.0CPython 2.7160154382240.03846153846155385.50530369184105Nuitka (master)160153380391.96153846153845385.5060457714495Nuitka (develop)160153527543.8846153846154385.505936903483Nuitka (factory)Construct GeneratorExitTicks Construct GeneratorExit 0010000000100000002000000020000000300000003000000040000000400000005000000050000000600000006000000070000000700000008000000080000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)8147021788.95192307692307257.0CPython 3.566203801242.31730769230768303.30607847206863Nuitka (master)66203368395.6826923076923303.3073918472563Nuitka (develop)66203366549.0480769230769303.3073979136544Nuitka (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_plain_generator; 53 static PyObject *const_str_plain_generator;
54 static PyObject *const_str_plain_repeat; 54 static PyObject *const_str_plain_repeat;
55 static PyObject *const_str_digest_e00f3b0cbd00d33a665cd735a9d08b6e; 55 static PyObject *const_str_digest_e00f3b0cbd00d33a665cd735a9d08b6e;
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_digest_e00f3b0cbd00d33a665cd735a9d08b6e = UNSTREAM_STRING_ASCII(&constant_bin[ 118 ], 38, 0); 88     const_str_digest_e00f3b0cbd00d33a665cd735a9d08b6e = UNSTREAM_STRING_ASCII(&constant_bin[ 118 ], 38, 0);
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. */
148     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL; 145     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
149     PyObject *exception_type = NULL; 146     PyObject *exception_type = NULL;
150     PyObject *exception_value = NULL; 147     PyObject *exception_value = NULL;
151     PyTracebackObject *exception_tb = NULL; 148     PyTracebackObject *exception_tb = NULL;
152     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 149     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
n n 150     static struct Nuitka_FrameObject *cache_frame_f330ff09ff70af5cd5ab4f8c392c6679 = NULL;
151     PyObject *tmp_return_value = NULL;
153     PyObject *exception_keeper_type_1; 152     PyObject *exception_keeper_type_1;
154     PyObject *exception_keeper_value_1; 153     PyObject *exception_keeper_value_1;
155     PyTracebackObject *exception_keeper_tb_1; 154     PyTracebackObject *exception_keeper_tb_1;
156     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 155     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
n 157     PyObject *exception_preserved_type_1; n
158     PyObject *exception_preserved_value_1;
159     PyTracebackObject *exception_preserved_tb_1;
160     int tmp_res;
161     bool tmp_result;
162     PyObject *exception_keeper_type_2;
163     PyObject *exception_keeper_value_2;
164     PyTracebackObject *exception_keeper_tb_2;
165     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_2;
166     static struct Nuitka_FrameObject *cache_frame_f330ff09ff70af5cd5ab4f8c392c6679 = NULL;
167     PyObject *tmp_return_value = NULL;
168     PyObject *exception_keeper_type_3;
169     PyObject *exception_keeper_value_3;
170     PyTracebackObject *exception_keeper_tb_3;
171     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
172 156
173     // Actual function body. 157     // Actual function body.
174     { 158     {
175         PyObject *tmp_assign_source_1; 159         PyObject *tmp_assign_source_1;
176         tmp_assign_source_1 = MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_generator(); 160         tmp_assign_source_1 = MAKE_FUNCTION___main__$$$function_1_calledRepeatedly$$$function_1_generator();
251             goto frame_exception_exit_1; 235             goto frame_exception_exit_1;
252         } 236         }
253         assert(var_throw == NULL); 237         assert(var_throw == NULL);
254         var_throw = tmp_assign_source_3; 238         var_throw = tmp_assign_source_3;
255     } 239     }
n 256     // Tried code: n
257     {
258         PyObject *tmp_called_name_2;
259         PyObject *tmp_call_result_1;
260         CHECK_OBJECT(var_throw);
261         tmp_called_name_2 = var_throw;
262         frame_f330ff09ff70af5cd5ab4f8c392c6679->m_frame.f_lineno = 37;
263         tmp_call_result_1 = CALL_FUNCTION_WITH_ARGS1(tmp_called_name_2, &PyTuple_GET_ITEM(const_tuple_type_GeneratorExit_tuple, 0));
264  
265         if (tmp_call_result_1 == NULL) {
266             assert(ERROR_OCCURRED());
267  
268             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
269  
270  
271             exception_lineno = 37;
272             type_description_1 = "oNoo";
273             goto try_except_handler_2;
274         }
275         Py_DECREF(tmp_call_result_1);
276     }
277     goto try_end_1;
278     // Exception handler code:
279     try_except_handler_2:;
280     exception_keeper_type_1 = exception_type;
281     exception_keeper_value_1 = exception_value;
282     exception_keeper_tb_1 = exception_tb;
283     exception_keeper_lineno_1 = exception_lineno;
284     exception_type = NULL;
285     exception_value = NULL;
286     exception_tb = NULL;
287     exception_lineno = 0;
288  
289     // Preserve existing published exception.
290     exception_preserved_type_1 = EXC_TYPE(PyThreadState_GET());
291     Py_XINCREF(exception_preserved_type_1);
292     exception_preserved_value_1 = EXC_VALUE(PyThreadState_GET());
293     Py_XINCREF(exception_preserved_value_1);
294     exception_preserved_tb_1 = (PyTracebackObject *)EXC_TRACEBACK(PyThreadState_GET());
295     Py_XINCREF(exception_preserved_tb_1);
296  
297     if (exception_keeper_tb_1 == NULL) {
298         exception_keeper_tb_1 = MAKE_TRACEBACK(frame_f330ff09ff70af5cd5ab4f8c392c6679, exception_keeper_lineno_1);
299     } else if (exception_keeper_lineno_1 != 0) {
300         exception_keeper_tb_1 = ADD_TRACEBACK(exception_keeper_tb_1, frame_f330ff09ff70af5cd5ab4f8c392c6679, exception_keeper_lineno_1);
301     }
302  
303     NORMALIZE_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
304     PyException_SetTraceback(exception_keeper_value_1, (PyObject *)exception_keeper_tb_1);
305     PUBLISH_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
306     // Tried code:
307     {
308         nuitka_bool tmp_condition_result_1;
309         PyObject *tmp_operand_name_1;
310         PyObject *tmp_compexpr_left_1;
311         PyObject *tmp_compexpr_right_1;
312         tmp_compexpr_left_1 = EXC_TYPE(PyThreadState_GET());
313         tmp_compexpr_right_1 = PyExc_GeneratorExit;
314         tmp_res = EXCEPTION_MATCH_BOOL(tmp_compexpr_left_1, tmp_compexpr_right_1);
315         if (tmp_res == -1) {
316             assert(ERROR_OCCURRED());
317  
318             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
319  
320  
321             exception_lineno = 41;
322             type_description_1 = "oNoo";
323             goto try_except_handler_3;
324         }
325         tmp_operand_name_1 = (tmp_res != 0) ? Py_True : Py_False;
326         tmp_res = CHECK_IF_TRUE(tmp_operand_name_1);
327         if (tmp_res == -1) {
328             assert(ERROR_OCCURRED());
329  
330             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
331  
332  
333             exception_lineno = 41;
334             type_description_1 = "oNoo";
335             goto try_except_handler_3;
336         }
337         tmp_condition_result_1 = (tmp_res == 0) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
338         if (tmp_condition_result_1 == NUITKA_BOOL_TRUE) {
339             goto branch_yes_1;
340         } else {
341             goto branch_no_1;
342         }
343         branch_yes_1:;
344         tmp_result = RERAISE_EXCEPTION(&exception_type, &exception_value, &exception_tb);
345         if (unlikely(tmp_result == false)) {
346             exception_lineno = 35;
347         }
348  
349         if (exception_tb && exception_tb->tb_frame == &frame_f330ff09ff70af5cd5ab4f8c392c6679->m_frame) frame_f330ff09ff70af5cd5ab4f8c392c6679->m_frame.f_lineno = exception_tb->tb_lineno;
350         type_description_1 = "oNoo";
351         goto try_except_handler_3;
352         branch_no_1:;
353     }
354     goto try_end_2;
355     // Exception handler code:
356     try_except_handler_3:;
357     exception_keeper_type_2 = exception_type;
358     exception_keeper_value_2 = exception_value;
359     exception_keeper_tb_2 = exception_tb;
360     exception_keeper_lineno_2 = exception_lineno;
361     exception_type = NULL;
362     exception_value = NULL;
363     exception_tb = NULL;
364     exception_lineno = 0;
365  
366     // Restore previous exception.
367     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
368     // Re-raise.
369     exception_type = exception_keeper_type_2;
370     exception_value = exception_keeper_value_2;
371     exception_tb = exception_keeper_tb_2;
372     exception_lineno = exception_keeper_lineno_2;
373  
374     goto frame_exception_exit_1;
375     // End of try:
376     try_end_2:;
377     // Restore previous exception.
378     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
379     goto try_end_1;
380     // exception handler codes exits in all cases
381     NUITKA_CANNOT_GET_HERE(__main__$$$function_1_calledRepeatedly);
382     return NULL;
383     // End of try:
384     try_end_1:;
385 240
386 #if 0 241 #if 0
387     RESTORE_FRAME_EXCEPTION(frame_f330ff09ff70af5cd5ab4f8c392c6679); 242     RESTORE_FRAME_EXCEPTION(frame_f330ff09ff70af5cd5ab4f8c392c6679);
388 #endif 243 #endif
389 244
461     var_generator = NULL; 316     var_generator = NULL;
462 317
463     goto function_return_exit; 318     goto function_return_exit;
464     // Exception handler code: 319     // Exception handler code:
465     try_except_handler_1:; 320     try_except_handler_1:;
n 466     exception_keeper_type_3 = exception_type; n 321     exception_keeper_type_1 = exception_type;
467     exception_keeper_value_3 = exception_value; 322     exception_keeper_value_1 = exception_value;
468     exception_keeper_tb_3 = exception_tb; 323     exception_keeper_tb_1 = exception_tb;
469     exception_keeper_lineno_3 = exception_lineno; 324     exception_keeper_lineno_1 = exception_lineno;
470     exception_type = NULL; 325     exception_type = NULL;
471     exception_value = NULL; 326     exception_value = NULL;
472     exception_tb = NULL; 327     exception_tb = NULL;
473     exception_lineno = 0; 328     exception_lineno = 0;
474 329
475     Py_XDECREF(var_gen); 330     Py_XDECREF(var_gen);
476     var_gen = NULL; 331     var_gen = NULL;
477 332
n 478     Py_XDECREF(var_throw); n
479     var_throw = NULL;
480  
481     CHECK_OBJECT((PyObject *)var_generator); 333     CHECK_OBJECT((PyObject *)var_generator);
482     Py_DECREF(var_generator); 334     Py_DECREF(var_generator);
483     var_generator = NULL; 335     var_generator = NULL;
484 336
485     // Re-raise. 337     // Re-raise.
t 486     exception_type = exception_keeper_type_3; t 338     exception_type = exception_keeper_type_1;
487     exception_value = exception_keeper_value_3; 339     exception_value = exception_keeper_value_1;
488     exception_tb = exception_keeper_tb_3; 340     exception_tb = exception_keeper_tb_1;
489     exception_lineno = exception_keeper_lineno_3; 341     exception_lineno = exception_keeper_lineno_1;
490 342
491     goto function_exception_exit; 343     goto function_exception_exit;
492     // End of try: 344     // End of try:
493 345
494     // Return statement must have exited already. 346     // Return statement must have exited already.