2023年政策修订增补工作正在进行中,欢迎参与!
Help:滥用过滤器使用指导/条件
跳转到导航
跳转到搜索
论述: 条件判断限制器是一种避免性能问题的特设工具。从某些程度上说,如果阁下非常关心性能问题,执行时间一般是一个极好的参考性能指标。每过滤器执行时间和条件判断数量有些时候并不准确(竞态条件可以导致它们出现了偏差),但是总体上来说它们也可以用作参考指标。
条件判断限制是一种比较运算符数量和函数(方法)调用数量的跟踪机制。然而它也可以在不影响结果的情形下机智地跳过函数(方法)和括号组。举个例子,在表达式 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
可能是),那么过滤器在多数情况只需要下消耗一个条件判断。
|