幫助:濫用過濾器使用指導/條件
跳至導覽
跳至搜尋
論述: 條件判斷限制器是一種避免性能問題的特設工具。從某些程度上說,如果閣下非常關心性能問題,執行時間一般是一個極好的參考性能指標。每過濾器執行時間和條件判斷數量有些時候並不準確(競態條件可以導致它們出現了偏差),但是總體上來說它們也可以用作參考指標。
條件判斷限制是一種比較運算符數量和函數(方法)調用數量的跟蹤機制。然而它也可以在不影響結果的情形下機智地跳過函數(方法)和括號組。舉個例子,在表達式 A & B 中,B 的情況只會在 A 為真時被評估。出於此理由,將簡單的條件(例如檢查文章命名空間)放在複雜的表達式前對性能是大有脾益的。最後需要注意的是,函數(方法)將會被緩存,所以它們只會在第一次被調用的時候增加條件判斷計數。
MediaWiki 1.27 之前
介於萌百的實際部署情況,此段不翻譯,請參考 to MediaWiki 1.27 Prior to MediaWiki 1.27 上的內容。
MediaWiki 1.27 和更新版本
實用建議
- 將容易評估但是難匹配條件的項目放在過濾器前面。這樣可以使得過濾器更快完成,且可以改善運行時間,減少條件判斷用量。
- 在文本里檢測多段文字的出現次數時(通常用於檢測垃圾信息),使用
contains_any(text, 'a', 'b', 'c')
或text rlike 'a|b|c'
遠快於 對每個字符串進行單獨的測試 ('a' in text | 'b' in text | 'c' in text
)。這樣也使用了更少的條件判斷。 - 所有除了
user_name
的user_*
變量可能需要一次數據庫查詢。因此,使用它們相比使用預定義變量如action
andarticle_namespace
來說成本更為昂貴。它們應該不被作為過濾器的第一個條件使用(取決於新的順序使得匹配的完成的耗時,這可能會減少或增加條件判斷計數,但應該改善了總體性能)。
常規計數
Rules | 使用的條件 | 備註 |
---|---|---|
'foo' == 'bar' |
1 | 一個計數為一次的簡單條件判斷。 |
'foo' == 'bar' | 'baz' == 'qaz' |
2 | |
'foo' == 'bar' & 'baz' == 'bar' |
1 | 不需要被評估來用於決定最終結果的測試沒有被計數。 (短路求值)
|
'foo' == 'foo' | 'baz' == 'qaz' |
1 | |
str_replace( 'FooFoo', 'Foo', '' ) == 'bar' |
2 | 每個函數(方法)調用被視作一次條件判斷計數。 |
str_replace( 'FooFoo', 'Foo', '' ) == 'bar' |
3 | 相同參數的同函數(方法)調用被視作僅一次條件判斷計數。 |
例子1
舉一個實際例子,考慮 英文維基百科的過濾器 #59:
article_namespace == 6 & !("autoconfirmed" in user_groups) & !(user_name in article_recent_contributors) & rcount ("\{\{.*\}\}", removed_lines) > rcount ("\{\{.*\}\}", added_lines)
這可以被簡化為:
- A & !B & !C & fun1() > fun2()
取決於變量的值,過濾器可以消耗1到6個條件判斷:
- 1 個條件判斷 (1 次比較) 如果第一個測試的值為假:剩下的測試將不會被評估
- 2 個條件判斷 (2 次比較) 如果第一個測試的值為真, 但第二個測試的值為假:剩下的測試將不會被評估
- 3 個條件判斷 (3 次比較) 如果第一個和第二個測試的值為真,但第三個測試的值為假:剩下的測試將不會被評估
- 6 個條件判斷 (3 次比較 + 2 次函數(方法)調用 + 1 次比較) 如果第一個、第二個和第三個測試的值為真
如果初始條件罕見地為真(比如 article_namespace == 6
可能是),那麼過濾器在多數情況只需要下消耗一個條件判斷。
|