Construct ClosureVariableAccess

Performance Diagrams

Construct ClosureVariableAccess 001000000100000020000002000000300000030000004000000400000050000005000000600000060000007000000700000080000008000000900000090000001000000010000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)1014775888.95192307692307257.0CPython 2.72800103242.31730769230768435.9280539944049Nuitka (master)2800259395.6826923076923435.9242551257287Nuitka (develop)2799673549.0480769230769435.93852523498674Nuitka (factory)Construct ClosureVariableAccessTicks Construct ClosureVariableAccess 00100000010000002000000200000030000003000000400000040000005000000500000060000006000000700000070000008000000800000090000009000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)907256389.78846153846155257.0CPython 3.53398907244.59615384615387411.53711201734114Nuitka (master)3398697399.4038461538462411.5428319259016Nuitka (develop)3402311554.2115384615385411.4443950233417Nuitka (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
347     PyObject *exception_type = NULL; 347     PyObject *exception_type = NULL;
348     PyObject *exception_value = NULL; 348     PyObject *exception_value = NULL;
349     PyTracebackObject *exception_tb = NULL; 349     PyTracebackObject *exception_tb = NULL;
350     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 350     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
351     PyObject *tmp_assign_source_1; 351     PyObject *tmp_assign_source_1;
n 352     PyObject *tmp_assign_source_2; n
353     PyObject *tmp_return_value; 352     PyObject *tmp_return_value;
354     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused; 353     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused;
355     static struct Nuitka_FrameObject *cache_frame_529da8469be24355bdb29c8c9c0585cf = NULL; 354     static struct Nuitka_FrameObject *cache_frame_529da8469be24355bdb29c8c9c0585cf = NULL;
356 355
357     struct Nuitka_FrameObject *frame_529da8469be24355bdb29c8c9c0585cf; 356     struct Nuitka_FrameObject *frame_529da8469be24355bdb29c8c9c0585cf;
409         exception_value = PyUnicode_FromFormat( "free variable '%s' referenced before assignment in enclosing scope", "closure_value" ); 408         exception_value = PyUnicode_FromFormat( "free variable '%s' referenced before assignment in enclosing scope", "closure_value" );
410         exception_tb = NULL; 409         exception_tb = NULL;
411         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb ); 410         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
412         CHAIN_EXCEPTION( exception_value ); 411         CHAIN_EXCEPTION( exception_value );
413 412
n 414         exception_lineno = 35; n
415         type_description_1 = "c";
416         goto frame_exception_exit_1;
417     }
418  
419     UPDATE_STRING_DICT0( moduledict___main__, (Nuitka_StringObject *)const_str_plain_module_value2, tmp_assign_source_1 );
420     if ( self->m_closure[0] == NULL )
421     {
422         tmp_assign_source_2 = NULL;
423     }
424     else
425     {
426         tmp_assign_source_2 = PyCell_GET( self->m_closure[0] );
427     }
428  
429     if ( tmp_assign_source_2 == NULL )
430     {
431  
432         exception_type = PyExc_NameError;
433         Py_INCREF( exception_type );
434         exception_value = PyUnicode_FromFormat( "free variable '%s' referenced before assignment in enclosing scope", "closure_value" );
435         exception_tb = NULL;
436         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
437         CHAIN_EXCEPTION( exception_value );
438  
439         exception_lineno = 38; 413         exception_lineno = 38;
440         type_description_1 = "c"; 414         type_description_1 = "c";
441         goto frame_exception_exit_1; 415         goto frame_exception_exit_1;
442     } 416     }
443 417
t 444     UPDATE_STRING_DICT0( moduledict___main__, (Nuitka_StringObject *)const_str_plain_module_value3, tmp_assign_source_2 ); t 418     UPDATE_STRING_DICT0( moduledict___main__, (Nuitka_StringObject *)const_str_plain_module_value3, tmp_assign_source_1 );
445 419
446 #if 0 420 #if 0
447     RESTORE_FRAME_EXCEPTION( frame_529da8469be24355bdb29c8c9c0585cf ); 421     RESTORE_FRAME_EXCEPTION( frame_529da8469be24355bdb29c8c9c0585cf );
448 #endif 422 #endif
449 423