Construct GeneratorExit

Performance Diagrams

Construct GeneratorExit 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)27566758188.11538461538461257.0CPython 2.7127900016240.03846153846155389.4625787558743Nuitka (master)127900016391.96153846153845389.4625787558743Nuitka (develop)127900016543.8846153846154389.4625787558743Nuitka (factory)Construct GeneratorExitTicks Construct GeneratorExit 0010000000100000002000000020000000300000003000000040000000400000005000000050000000600000006000000070000000700000008000000080000000CPython 3.8Nuitka (master)Nuitka (develop)Nuitka (factory)8276988688.95192307692307257.0CPython 3.858804745242.31730769230768328.54963383152324Nuitka (master)58804787395.6826923076923328.54950843753454Nuitka (develop)58803760549.0480769230769328.55257461911657Nuitka (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
110 110
111     // Local variable declarations. 111     // Local variable declarations.
112     PyObject *var_generator = NULL; 112     PyObject *var_generator = NULL;
113     PyObject *var_gen = NULL; 113     PyObject *var_gen = NULL;
114     PyObject *var_throw = NULL; 114     PyObject *var_throw = NULL;
n 115     PyObject *var_exc = NULL; n
116     struct Nuitka_FrameObject *frame_4c7e307517e9b68fe26406b6daeb1c05; 115     struct Nuitka_FrameObject *frame_4c7e307517e9b68fe26406b6daeb1c05;
117     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL; 116     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
118     PyObject *exception_type = NULL; 117     PyObject *exception_type = NULL;
119     PyObject *exception_value = NULL; 118     PyObject *exception_value = NULL;
120     PyTracebackObject *exception_tb = NULL; 119     PyTracebackObject *exception_tb = NULL;
121     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 120     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
122     NUITKA_MAY_BE_UNUSED nuitka_void tmp_unused; 121     NUITKA_MAY_BE_UNUSED nuitka_void tmp_unused;
n n 122     static struct Nuitka_FrameObject *cache_frame_4c7e307517e9b68fe26406b6daeb1c05 = NULL;
123     PyObject *tmp_return_value = NULL;
123     PyObject *exception_keeper_type_1; 124     PyObject *exception_keeper_type_1;
124     PyObject *exception_keeper_value_1; 125     PyObject *exception_keeper_value_1;
125     PyTracebackObject *exception_keeper_tb_1; 126     PyTracebackObject *exception_keeper_tb_1;
126     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 127     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
n 127     PyObject *exception_preserved_type_1; n
128     PyObject *exception_preserved_value_1;
129     PyTracebackObject *exception_preserved_tb_1;
130     int tmp_res;
131     bool tmp_result;
132     PyObject *exception_keeper_type_2;
133     PyObject *exception_keeper_value_2;
134     PyTracebackObject *exception_keeper_tb_2;
135     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_2;
136     static struct Nuitka_FrameObject *cache_frame_4c7e307517e9b68fe26406b6daeb1c05 = NULL;
137     PyObject *tmp_return_value = NULL;
138     PyObject *exception_keeper_type_3;
139     PyObject *exception_keeper_value_3;
140     PyTracebackObject *exception_keeper_tb_3;
141     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
142 128
143     // Actual function body. 129     // Actual function body.
144     { 130     {
145         PyObject *tmp_assign_source_1; 131         PyObject *tmp_assign_source_1;
146 132
190 176
191             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb); 177             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
192 178
193 179
194             exception_lineno = 27; 180             exception_lineno = 27;
n 195             type_description_1 = "oooo"; n 181             type_description_1 = "oooN";
196             goto frame_exception_exit_1; 182             goto frame_exception_exit_1;
197         } 183         }
198         assert(var_gen == NULL); 184         assert(var_gen == NULL);
199         var_gen = tmp_assign_source_2; 185         var_gen = tmp_assign_source_2;
200     } 186     }
213             } else { 199             } else {
214                 FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb); 200                 FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
215             } 201             }
216 202
217 203
n 218             type_description_1 = "oooo"; n 204             type_description_1 = "oooN";
219             exception_lineno = 29; 205             exception_lineno = 29;
220             goto frame_exception_exit_1; 206             goto frame_exception_exit_1;
221         } 207         }
222         Py_DECREF(tmp_next_value_1); 208         Py_DECREF(tmp_next_value_1);
223     } 209     }
232 218
233             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb); 219             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
234 220
235 221
236             exception_lineno = 32; 222             exception_lineno = 32;
n 237             type_description_1 = "oooo"; n 223             type_description_1 = "oooN";
238             goto frame_exception_exit_1; 224             goto frame_exception_exit_1;
239         } 225         }
240         assert(var_throw == NULL); 226         assert(var_throw == NULL);
241         var_throw = tmp_assign_source_3; 227         var_throw = tmp_assign_source_3;
242     } 228     }
n 243     { n
244         PyObject *tmp_assign_source_4;
245         tmp_assign_source_4 = PyExc_GeneratorExit;
246         assert(var_exc == NULL);
247         Py_INCREF(tmp_assign_source_4);
248         var_exc = tmp_assign_source_4;
249     }
250     // Tried code:
251     {
252         PyObject *tmp_called_name_2;
253         PyObject *tmp_call_result_1;
254         PyObject *tmp_args_element_name_1;
255         CHECK_OBJECT(var_throw);
256         tmp_called_name_2 = var_throw;
257         CHECK_OBJECT(var_exc);
258         tmp_args_element_name_1 = var_exc;
259         frame_4c7e307517e9b68fe26406b6daeb1c05->m_frame.f_lineno = 37;
260         tmp_call_result_1 = CALL_FUNCTION_WITH_SINGLE_ARG(tmp_called_name_2, tmp_args_element_name_1);
261         if (tmp_call_result_1 == NULL) {
262             assert(ERROR_OCCURRED());
263  
264             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
265  
266  
267             exception_lineno = 37;
268             type_description_1 = "oooo";
269             goto try_except_handler_2;
270         }
271         Py_DECREF(tmp_call_result_1);
272     }
273     goto try_end_1;
274     // Exception handler code:
275     try_except_handler_2:;
276     exception_keeper_type_1 = exception_type;
277     exception_keeper_value_1 = exception_value;
278     exception_keeper_tb_1 = exception_tb;
279     exception_keeper_lineno_1 = exception_lineno;
280     exception_type = NULL;
281     exception_value = NULL;
282     exception_tb = NULL;
283     exception_lineno = 0;
284  
285     // Preserve existing published exception id 1.
286     GET_CURRENT_EXCEPTION(&exception_preserved_type_1, &exception_preserved_value_1, &exception_preserved_tb_1);
287  
288     if (exception_keeper_tb_1 == NULL) {
289         exception_keeper_tb_1 = MAKE_TRACEBACK(frame_4c7e307517e9b68fe26406b6daeb1c05, exception_keeper_lineno_1);
290     } else if (exception_keeper_lineno_1 != 0) {
291         exception_keeper_tb_1 = ADD_TRACEBACK(exception_keeper_tb_1, frame_4c7e307517e9b68fe26406b6daeb1c05, exception_keeper_lineno_1);
292     }
293  
294     NORMALIZE_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
295     ATTACH_TRACEBACK_TO_EXCEPTION_VALUE(exception_keeper_value_1, exception_keeper_tb_1);
296     PUBLISH_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
297     // Tried code:
298     {
299         bool tmp_condition_result_1;
300         PyObject *tmp_compexpr_left_1;
301         PyObject *tmp_compexpr_right_1;
302         tmp_compexpr_left_1 = EXC_TYPE(PyThreadState_GET());
303         CHECK_OBJECT(var_exc);
304         tmp_compexpr_right_1 = var_exc;
305         tmp_res = EXCEPTION_MATCH_BOOL(tmp_compexpr_left_1, tmp_compexpr_right_1);
306         if (tmp_res == -1) {
307             assert(ERROR_OCCURRED());
308  
309             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
310  
311  
312             exception_lineno = 41;
313             type_description_1 = "oooo";
314             goto try_except_handler_3;
315         }
316         tmp_condition_result_1 = (tmp_res == 0) ? true : false;
317         if (tmp_condition_result_1 != false) {
318             goto branch_yes_1;
319         } else {
320             goto branch_no_1;
321         }
322     }
323     branch_yes_1:;
324     tmp_result = RERAISE_EXCEPTION(&exception_type, &exception_value, &exception_tb);
325     if (unlikely(tmp_result == false)) {
326         exception_lineno = 35;
327     }
328  
329     if (exception_tb && exception_tb->tb_frame == &frame_4c7e307517e9b68fe26406b6daeb1c05->m_frame) frame_4c7e307517e9b68fe26406b6daeb1c05->m_frame.f_lineno = exception_tb->tb_lineno;
330     type_description_1 = "oooo";
331     goto try_except_handler_3;
332     branch_no_1:;
333     goto try_end_2;
334     // Exception handler code:
335     try_except_handler_3:;
336     exception_keeper_type_2 = exception_type;
337     exception_keeper_value_2 = exception_value;
338     exception_keeper_tb_2 = exception_tb;
339     exception_keeper_lineno_2 = exception_lineno;
340     exception_type = NULL;
341     exception_value = NULL;
342     exception_tb = NULL;
343     exception_lineno = 0;
344  
345     // Restore previous exception id 1.
346     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
347  
348     // Re-raise.
349     exception_type = exception_keeper_type_2;
350     exception_value = exception_keeper_value_2;
351     exception_tb = exception_keeper_tb_2;
352     exception_lineno = exception_keeper_lineno_2;
353  
354     goto frame_exception_exit_1;
355     // End of try:
356     try_end_2:;
357     // Restore previous exception id 1.
358     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
359  
360     goto try_end_1;
361     NUITKA_CANNOT_GET_HERE("exception handler codes exits in all cases");
362     return NULL;
363     // End of try:
364     try_end_1:;
365 229
366 #if 0 230 #if 0
367     RESTORE_FRAME_EXCEPTION(frame_4c7e307517e9b68fe26406b6daeb1c05); 231     RESTORE_FRAME_EXCEPTION(frame_4c7e307517e9b68fe26406b6daeb1c05);
368 #endif 232 #endif
369 233
389         frame_4c7e307517e9b68fe26406b6daeb1c05, 253         frame_4c7e307517e9b68fe26406b6daeb1c05,
390         type_description_1, 254         type_description_1,
391         var_generator, 255         var_generator,
392         var_gen, 256         var_gen,
393         var_throw, 257         var_throw,
n 394         var_exc n 258         NULL
395     ); 259     );
396 260
397 261
398     // Release cached frame if used for exception. 262     // Release cached frame if used for exception.
399     if (frame_4c7e307517e9b68fe26406b6daeb1c05 == cache_frame_4c7e307517e9b68fe26406b6daeb1c05) { 263     if (frame_4c7e307517e9b68fe26406b6daeb1c05 == cache_frame_4c7e307517e9b68fe26406b6daeb1c05) {
419         PyObject *tmp_tuple_element_1; 283         PyObject *tmp_tuple_element_1;
420         CHECK_OBJECT(var_throw); 284         CHECK_OBJECT(var_throw);
421         tmp_tuple_element_1 = var_throw; 285         tmp_tuple_element_1 = var_throw;
422         tmp_return_value = PyTuple_New(2); 286         tmp_return_value = PyTuple_New(2);
423         PyTuple_SET_ITEM0(tmp_return_value, 0, tmp_tuple_element_1); 287         PyTuple_SET_ITEM0(tmp_return_value, 0, tmp_tuple_element_1);
n 424         CHECK_OBJECT(var_exc); n
425         tmp_tuple_element_1 = var_exc; 288         tmp_tuple_element_1 = PyExc_GeneratorExit;
426         PyTuple_SET_ITEM0(tmp_return_value, 1, tmp_tuple_element_1); 289         PyTuple_SET_ITEM0(tmp_return_value, 1, tmp_tuple_element_1);
427         goto try_return_handler_1; 290         goto try_return_handler_1;
428     } 291     }
429     NUITKA_CANNOT_GET_HERE("tried codes exits in all cases"); 292     NUITKA_CANNOT_GET_HERE("tried codes exits in all cases");
430     return NULL; 293     return NULL;
437     Py_DECREF(var_gen); 300     Py_DECREF(var_gen);
438     var_gen = NULL; 301     var_gen = NULL;
439     CHECK_OBJECT(var_throw); 302     CHECK_OBJECT(var_throw);
440     Py_DECREF(var_throw); 303     Py_DECREF(var_throw);
441     var_throw = NULL; 304     var_throw = NULL;
n 442     CHECK_OBJECT(var_exc); n
443     Py_DECREF(var_exc);
444     var_exc = NULL;
445     goto function_return_exit; 305     goto function_return_exit;
446     // Exception handler code: 306     // Exception handler code:
447     try_except_handler_1:; 307     try_except_handler_1:;
n 448     exception_keeper_type_3 = exception_type; n 308     exception_keeper_type_1 = exception_type;
449     exception_keeper_value_3 = exception_value; 309     exception_keeper_value_1 = exception_value;
450     exception_keeper_tb_3 = exception_tb; 310     exception_keeper_tb_1 = exception_tb;
451     exception_keeper_lineno_3 = exception_lineno; 311     exception_keeper_lineno_1 = exception_lineno;
452     exception_type = NULL; 312     exception_type = NULL;
453     exception_value = NULL; 313     exception_value = NULL;
454     exception_tb = NULL; 314     exception_tb = NULL;
455     exception_lineno = 0; 315     exception_lineno = 0;
456 316
457     CHECK_OBJECT(var_generator); 317     CHECK_OBJECT(var_generator);
458     Py_DECREF(var_generator); 318     Py_DECREF(var_generator);
459     var_generator = NULL; 319     var_generator = NULL;
460     Py_XDECREF(var_gen); 320     Py_XDECREF(var_gen);
461     var_gen = NULL; 321     var_gen = NULL;
n 462     Py_XDECREF(var_throw); n
463     var_throw = NULL;
464     Py_XDECREF(var_exc);
465     var_exc = NULL;
466     // Re-raise. 322     // Re-raise.
t 467     exception_type = exception_keeper_type_3; t 323     exception_type = exception_keeper_type_1;
468     exception_value = exception_keeper_value_3; 324     exception_value = exception_keeper_value_1;
469     exception_tb = exception_keeper_tb_3; 325     exception_tb = exception_keeper_tb_1;
470     exception_lineno = exception_keeper_lineno_3; 326     exception_lineno = exception_keeper_lineno_1;
471 327
472     goto function_exception_exit; 328     goto function_exception_exit;
473     // End of try: 329     // End of try:
474 330
475     NUITKA_CANNOT_GET_HERE("Return statement must have exited already."); 331     NUITKA_CANNOT_GET_HERE("Return statement must have exited already.");