置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

帮助:滥用过滤器使用指导/条件

萌娘百科,万物皆可萌的百科全书!转载请标注来源页面的网页链接,并声明引自萌娘百科。内容不可商用。
跳到导航 跳到搜索
Commons-emblem-notice.svg
这个页面“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_nameuser_* 变量可能需要一次数据库查询。因此,使用它们相比使用预定义变量如 action and article_namespace 来说成本更为昂贵。它们应该不被作为过滤器的第一个条件使用(取决于新的顺序使得匹配的完成的耗时,这可能会减少或增加条件判断计数,但应该改善了总体性能)。


常规计数

条件判断计数
Rules 使用的条件 备注
'foo' == 'bar' 1 一个计数为一次的简单条件判断。
'foo' == 'bar' | 'baz' == 'qaz' 2
'foo' == 'bar' & 'baz' == 'bar' 1 不需要被评估来用于决定最终结果的测试没有被计数。 (短路求值)
  • 在第一个例子中, 'foo' == 'bar' 为假, 所以第二个测试对最终结果没有影响(结果均为假)。
  • 在第二个例子中, 'foo' == 'foo' 为真, 所以第二个测试对最终结果没有影响(结果均为真)。
'foo' == 'foo' | 'baz' == 'qaz' 1
str_replace( 'FooFoo', 'Foo', '' ) == 'bar' 2 每个函数(方法)调用被视作一次条件判断计数。
str_replace( 'FooFoo', 'Foo', '' ) == 'bar'
| str_replace( 'FooFoo', 'Foo', '' ) == 'baz'
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 可能是),那么过滤器在多数情况只需要下消耗一个条件判断。