2017-06-19 17 views
1

這是一個普遍的問題的東西。假設TCL 8.6,讓我們來看看我有一個相當短的程序。我有2種方法返回所關心的價值:
1.使用一些標準做法的if/else代碼,存儲在一個變量,並返回變量的值。例如:
吹毛求疵:TCL存放在變量與否,對於速度,程序

proc me { gop goo } { 
    if { [ lomsa $gop ] { 
     set ret [ foo $goo $gop ] 
    } else { 
     set ret [ bar $gop $goo ] 
    } 
    return $ret 
} 

2.使用三元參數,並且基本上,具有程序不添加專用變量(即,僅使用參數)。三元表達式的輸出是返回值。例如:

proc me { gop goo } { 
    expr { [ lomsa $gop ] ? [ foo $goo $gop ] : [ bar $gop $goo ] } 
} 

可讀性是由我的團隊的一些成員認爲是更好的項目稍好1.
我無法訪問的僞代碼引擎在我的TCL設置(這是從一個shell一個供應商),但我認爲代碼中的差異,以及它的性能會是,但只是輕微的,如果有的話。即,程序需要存儲返回值的某個地方。註冊一個特定變量的成本是多少,而不僅僅是將其作爲一個返回值?
這個問題可以擴展,例如,switch語句。相同的規則適用。 switch語句可以在一個變量存儲,然後,在開關後,將返回變量的值,或switch語句將只返回值,W/O將其存儲在一個變量。另外,在返回部分之前可以有大量的代碼。上述程序上市是他們所謂的「方便過程」
你可以認爲性能是代碼的高利息。

回答

1

除了可讀性,三元運營商可能會產生意想不到的效果。例如,如果所選的proc返回0123,則您的me proc將返回83。所以除非你確定這種情況永遠不會發生,否則使用if命令會更安全。

+0

哇!我需要開一個新的問題來理解爲什麼會發生這種情況。 – user1134991

1

編譯成字節碼,命令兩個版本都沒有很大的不同:在兩種情況下,選擇結構被轉換爲分支指令。

要大致看看你的代碼將是什麼樣子編譯並準備運行,使用tcl::unsupported::disassemble proc <name-of-proc>。一些注意事項:該命令不受支持,這意味着它不能保證按照您期望的方式工作,或保持現在在將來版本中的工作方式。除非您非常熟悉字節碼解釋器的工作方式,否則查看反彙編列表也可能會讓人誤以爲您可能會想到。

要了解有關性能的更多信息,您應該查看time命令和bench程序包,這些程序包對於衡量性能非常有用。

文檔: bench (package)time

+0

我知道使用時間。我對引擎蓋下的東西感興趣。更深入的瞭解... – user1134991

+0

@ user1134991:你是否也熟悉'tcl :: unsupported :: disassemble'? –

0

怎麼樣的中間立場?

proc me { gop goo } { 
    if { [lomsa $gop] } { 
     foo $goo $gop 
    } else { 
     bar $gop $goo 
    } 
} 

,或者如果你喜歡一個明確的回報:

proc me { gop goo } { 
    if { [lomsa $gop] } { 
     return [foo $goo $gop] 
    } else { 
     return [bar $gop $goo] 
    } 
} 
+0

最後一個因爲參數應該按不同的順序而中斷。 –

+0

的確,我錯過了。他們看起來太相似了。 –

2

有疑問時,不要猜測; time吧!

爲了您的示例代碼,在性能上的差異爲lomsafoobar最瑣碎的實現幾個百分點之內,我可以逃脫(在其下方有在一些細微的技術差別的理解少數邊緣情況)。對於任何更復雜的,你下來,你正在平衡局部變量的成本噪音訪問與額外調用該值轉換爲可能的話數值的操作碼,以及究竟是慢有「這取決於」領土。

switch聲明,當它處理它可以編譯在所有的情況下,使用Tcl的計算堆棧作爲臨時存儲。是我再次寫字節碼編譯,我可能會使用一個臨時的局部變量(他們是無名的,你不能觸摸它們從你的代碼),從而保持其他一些計算更簡單。要知道哪個是最快的選項,請記下您的實際代碼;對一些不太複雜的代理代碼進行計時可能會輕易得出相反的結論

在未來,差異應該變得較次。我們正在努力編譯有效的本地代碼。我們開發的編譯策略幾乎可以消除你在上面看到的實際代碼生成之前所看到的差異。