我想知道通过的字符列表\w
,是[a-zA-Z0-9_]
还是可以覆盖更多字符?
我问这个问题,是因为基于此,\d
是不同的[0-9]
,是低效率的。
\w
vs[a-zA-Z0-9_]
:大规模运行哪个可能更快?
[此答案是Perl特定的。其中的信息可能不适用于PCRE或其他已标记语言使用的引擎。]
/\w/aa
(实际等于/[a-zA-Z0-9_]/
)通常更快,但并非总是如此。也就是说,差异是如此之小(每次检查少于1纳秒),因此不必担心。放到上下文中,调用一个子程序或启动正则表达式引擎花费的时间要长得多。
接下来的内容将对此进行详细介绍。
首先,\w
与[a-zA-Z0-9_]
默认设置不同。\w
匹配每个字母,数字,标记和连接器标点的Unicode Code Point。其中有119,821![1]确定哪个是最快的非等效代码是没有道理的。
但是,使用\w
with/aa
可确保\w
仅match [a-zA-Z0-9_]
。这就是我们将用于基准测试的内容。(实际上,我们将两者同时使用。)
(请注意,每个测试执行1000万次检查,因此10.0 / s的速率实际上意味着每秒1000万次检查。)
ASCII-only positive match
Rate [a-zA-Z0-9_] (?u:\w) (?aa:\w)
[a-zA-Z0-9_] 39.1/s -- -26% -36%
(?u:\w) 52.9/s 35% -- -13%
(?aa:\w) 60.9/s 56% 15% --
当找到ASCII字符匹配时,纯ASCII\w
和Unicode\w
都击败了显式类。
/\w/aa
在我的机器上快了(1 / 39.1-1 / 60.9)/ 10,000,000 = 0.000,000,000,916 s
ASCII-only negative match
Rate (?u:\w) (?aa:\w) [a-zA-Z0-9_]
(?u:\w) 27.2/s -- -0% -12%
(?aa:\w) 27.2/s 0% -- -12%
[a-zA-Z0-9_] 31.1/s 14% 14% --
如果无法找到ASCII字符中的匹配项,则显式类将击败ASCII-only \w
。
/[a-zA-Z0-9_]/
在我的机器上快了(1 / 27.2-1 / 31.1)/ 10,000,000 = 0.000,000,000,461 s
Non-ASCII positive match
Rate (?u:\w) [a-zA-Z0-9_] (?aa:\w)
(?u:\w) 2.97/s -- -100% -100%
[a-zA-Z0-9_] 3349/s 112641% -- -9%
(?aa:\w) 3664/s 123268% 9% --
哇 该测试似乎正在进行一些优化。就是说,多次运行测试会产生非常一致的结果。(其他测试也一样。)
当找到非ASCII字符的匹配项时,仅ASCII会\w
击败显式类。
/\w/aa
在我的机器上快了(1/3349-1/3664)/ 10,000,000 = 0.000,000,000,002,57 s
Non-ASCII negative match
Rate (?u:\w) [a-zA-Z0-9_] (?aa:\w)
(?u:\w) 2.66/s -- -9% -71%
[a-zA-Z0-9_] 2.91/s 10% -- -68%
(?aa:\w) 9.09/s 242% 212% --
如果找不到非ASCII字符的匹配项,则仅ASCII会\w
击败显式类。
/[a-zA-Z0-9_]/
在我的机器上快了(1 / 2.91-1 / 9.09)/ 10,000,000 = 0.000,000,002,34 s
结论
/\w/aa
和之间有任何区别/[a-zA-Z0-9_]/
。/\w/aa
速度更快;在其他人中,/[a-zA-Z0-9_]/
。/\w/aa
和之间的差异/[a-zA-Z0-9_]/
非常小(小于1纳秒)。/\w/aa
,并/\w/u
是,尽管后者匹配4个数量级比以前更多的字符相当小。use strict;
use warnings;
use feature qw( say );
use Benchmarks qw( cmpthese );
my %pos_tests = (
'(?u:\\w)' => '/^\\w*\\z/u',
'(?aa:\\w)' => '/^\\w*\\z/aa',
'[a-zA-Z0-9_]' => '/^[a-zA-Z0-9_]*\\z/',
);
my %neg_tests = (
'(?u:\\w)' => '/\\w/u',
'(?aa:\\w)' => '/\\w/aa',
'[a-zA-Z0-9_]' => '/[a-zA-Z0-9_]/',
);
$_ = sprintf( 'use strict; use warnings; our $s; for (1..1000) { $s =~ %s }', $_)
for
values(%pos_tests),
values(%neg_tests);
local our $s;
say "ASCII-only positive match";
$s = "J" x 10_000;
cmpthese(-3, \%pos_tests);
say "";
say "ASCII-only negative match";
$s = "!" x 10_000;
cmpthese(-3, \%neg_tests);
say "";
say "Non-ASCII positive match";
$s = "\N{U+0100}" x 10_000;
cmpthese(-3, \%pos_tests);
say "";
say "Non-ASCII negative match";
$s = "\N{U+2660}" x 10_000;
cmpthese(-3, \%neg_tests);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句