Construct ClosureVariableAccess

Performance Diagrams

Construct ClosureVariableAccess 001000000100000020000002000000300000030000004000000400000050000005000000600000060000007000000700000080000008000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)853491689.78846153846155257.0CPython 2.72700171244.59615384615387425.9360803091316Nuitka (master)2700153399.4038461538462425.9366014714867Nuitka (develop)2700165554.2115384615385425.93625402991665Nuitka (factory)Construct ClosureVariableAccessTicks Construct ClosureVariableAccess 0010000001000000200000020000003000000300000040000004000000500000050000006000000600000070000007000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)792507889.78846153846155257.0CPython 3.53097277244.59615384615387407.53781186273983Nuitka (master)3100271399.4038461538462407.44445461609337Nuitka (develop)3100607554.2115384615385407.4339776505378Nuitka (factory)Construct ClosureVariableAccessTicks

Source Code with Construct

module_value1 = 1000
module_value2 = None
module_value3 = None

def calledRepeatedly():
    closure_value = module_value1

    def f():
        # Force frame and eliminate forward propagation (currently).
        module_value1

        # Use writing to global variable as access method.
        global module_value2, module_value3

# construct_begin
        module_value2 = closure_value
# construct_end

        module_value3 = closure_value

    f()

import itertools
for x in itertools.repeat(None, 50000):
    calledRepeatedly()

print("OK.")

Source Code without Construct

module_value1 = 1000
module_value2 = None
module_value3 = None

def calledRepeatedly():
    closure_value = module_value1

    def f():
        # Force frame and eliminate forward propagation (currently).
        module_value1

        # Use writing to global variable as access method.
        global module_value2, module_value3

# construct_begin



        module_value3 = closure_value

    f()

import itertools
for x in itertools.repeat(None, 50000):
    calledRepeatedly()

print("OK.")

Context Diff of Source Code


Construct
Baseline
30 30
31         # Use writing to global variable as access method. 31         # Use writing to global variable as access method.
32         global module_value2, module_value3 32         global module_value2, module_value3
33 33
34 # construct_begin 34 # construct_begin
t 35         module_value2 = closure_value t 35  
36 # construct_end 36  
37 37
38         module_value3 = closure_value 38         module_value3 = closure_value
39 39
40     f() 40     f()
41 41

Context Diff of Generated Code


Construct
Baseline
341     PyObject *exception_type = NULL; 341     PyObject *exception_type = NULL;
342     PyObject *exception_value = NULL; 342     PyObject *exception_value = NULL;
343     PyTracebackObject *exception_tb = NULL; 343     PyTracebackObject *exception_tb = NULL;
344     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 344     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
345     PyObject *tmp_assign_source_1; 345     PyObject *tmp_assign_source_1;
n 346     PyObject *tmp_assign_source_2; n
347     PyObject *tmp_return_value; 346     PyObject *tmp_return_value;
348     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused; 347     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused;
349     static struct Nuitka_FrameObject *cache_frame_126d26a3fd693b22979e89e63b8e1b45 = NULL; 348     static struct Nuitka_FrameObject *cache_frame_126d26a3fd693b22979e89e63b8e1b45 = NULL;
350 349
351     struct Nuitka_FrameObject *frame_126d26a3fd693b22979e89e63b8e1b45; 350     struct Nuitka_FrameObject *frame_126d26a3fd693b22979e89e63b8e1b45;
403         exception_value = PyUnicode_FromFormat( "free variable '%s' referenced before assignment in enclosing scope", "closure_value" ); 402         exception_value = PyUnicode_FromFormat( "free variable '%s' referenced before assignment in enclosing scope", "closure_value" );
404         exception_tb = NULL; 403         exception_tb = NULL;
405         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb ); 404         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
406         CHAIN_EXCEPTION( exception_value ); 405         CHAIN_EXCEPTION( exception_value );
407 406
n 408         exception_lineno = 35; n
409         type_description = "c";
410         goto frame_exception_exit_1;
411     }
412  
413     UPDATE_STRING_DICT0( moduledict___main__, (Nuitka_StringObject *)const_str_plain_module_value2, tmp_assign_source_1 );
414     if ( self->m_closure[0] == NULL )
415     {
416         tmp_assign_source_2 = NULL;
417     }
418     else
419     {
420         tmp_assign_source_2 = PyCell_GET( self->m_closure[0] );
421     }
422  
423     if ( tmp_assign_source_2 == NULL )
424     {
425  
426         exception_type = PyExc_NameError;
427         Py_INCREF( exception_type );
428         exception_value = PyUnicode_FromFormat( "free variable '%s' referenced before assignment in enclosing scope", "closure_value" );
429         exception_tb = NULL;
430         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
431         CHAIN_EXCEPTION( exception_value );
432  
433         exception_lineno = 38; 407         exception_lineno = 38;
434         type_description = "c"; 408         type_description = "c";
435         goto frame_exception_exit_1; 409         goto frame_exception_exit_1;
436     } 410     }
437 411
t 438     UPDATE_STRING_DICT0( moduledict___main__, (Nuitka_StringObject *)const_str_plain_module_value3, tmp_assign_source_2 ); t 412     UPDATE_STRING_DICT0( moduledict___main__, (Nuitka_StringObject *)const_str_plain_module_value3, tmp_assign_source_1 );
439 413
440 #if 0 414 #if 0
441     RESTORE_FRAME_EXCEPTION( frame_126d26a3fd693b22979e89e63b8e1b45 ); 415     RESTORE_FRAME_EXCEPTION( frame_126d26a3fd693b22979e89e63b8e1b45 );
442 #endif 416 #endif
443 417