Глобальная переменная TCL против двойной двоеточия - PullRequest
1 голос
/ 15 мая 2019

В TCL какая разница между кодом:

global MyVar
set MyVar 5

и код

set ::MyVar 5 

? Насколько я понимаю, MyVar означает, что MyVar будет глобальной переменной. Так в чем же разница?

1 Ответ

4 голосов
/ 15 мая 2019

Если это в процедуре, нет никакой функциональной разницы в том, какая переменная установлена ​​или какое значение помещено в нее. (global не действует вне процедур и других вещей с таблицами локальных переменных, такими как лямбда-выражения и методы.)

Там, где есть реальная разница, в том, как именно все делается. В частности, global настраивает один раз так, чтобы будущие неквалифицированные обращения к переменным были быстрыми, тогда как использование квалифицированной формы всегда делает полный поиск (который может включать несколько обращений к хеш-таблице). Эффект таков, что хотя одно чтение или запись выполняется быстрее с полностью определенной формой, множественный доступ всегда выполняется быстрее, если выполняется с помощью global (и эффект становится немного сильнее с несколькими переменными в вызове global, как некоторые из расходы амортизируются).

Но не верьте мне на слово. Сделайте несколько примеров процедур и проверьте себя с помощью time, возможно, так:

proc write1 {} {
    global MyVar
    set MyVar 5
    return
}
proc write2 {} {
    global MyVar
    set MyVar 5
    set MyVar 5
    return
}
proc write3 {} {
    global MyVar MyOtherVar
    set MyVar 5
    set MyOtherVar 5
    return
}
proc write4 {} {
    global MyVar MyOtherVar
    set MyVar 5
    set MyOtherVar 5
    set MyVar 5
    set MyOtherVar 5
    return
}
proc write5 {} {
    set ::MyVar 5
    return
}
proc write6 {} {
    set ::MyVar 5
    set ::MyVar 5
    return
}
proc write7 {} {
    set ::MyVar 5
    set ::MyOtherVar 5
    return
}
proc write8 {} {
    set ::MyVar 5
    set ::MyOtherVar 5
    set ::MyVar 5
    set ::MyOtherVar 5
    return
}

foreach cmd {write1 write2 write3 write4 write5 write6 write7 write8} {
    # Execute once to ensure everything is internally optimised
    $cmd
    # Now the timing run
    puts "$cmd : [time { $cmd } 100000]"
}

На моем ноутбуке (уже несколько лет) под управлением Tcl 8.6.9 я получаю следующее:

write1 : 0.62610808 microseconds per iteration
write2 : 0.63969525 microseconds per iteration
write3 : 0.73437284 microseconds per iteration
write4 : 0.7519245699999999 microseconds per iteration
write5 : 0.62230006 microseconds per iteration
write6 : 0.8437912799999999 microseconds per iteration
write7 : 0.8246234299999999 microseconds per iteration
write8 : 1.2297289900000001 microseconds per iteration

Как вы можете видеть (и подтвердить это на своем оборудовании), write1 медленнее, чем write5, но для каждой из других пар использование global является выигрышем в производительности. (Я немного удивлен, что write3 бьет write7, но цифры не лгут.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...