我怀疑问题的部分原因在于您的“C 代码”与 C 代码不太一样。例如,在 C 中,您不能将序列\"
放在一对引号之外,例如单引号或双引号。
我调整了正则表达式以使其可读并将其包装到一个简单的脚本中,该脚本会破坏其输入并将正则表达式应用于它:
#!/usr/bin/env perl
### Original regex from PerlFAQ6.
### s#/\*[^*]*\*+([^/*][^*]*\*+)*/|//([^\\]|[^\n][\n]?)*?\n|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $3 ? $3 : ""#gse;
undef $/; # Slurp input
while (<>)
{
print "raw: $_";
s%
/\*[^*]*\*+([^/*][^*]*\*+)*/ # Simple C comments
| //([^\\]|[^\n][\n]?)*?\n # C++ comments, allowing for backslash-newline continuation
| (
"(\\.|[^"\\])*" # Double-quoted strings
| '(\\.|[^'\\])*' # Single-quoted characters
| .[^/"'\\]* # Anything else
)
% defined $3 ? $3 : ""
%egsx;
print "out: $_";
}
我采用了您的非 C 代码行,并创建了文件 data.1、data.2、data.4、data.8、...、data.1024,每个文件都有适当的行数。然后我运行了一个计时循环。
$ for x in 1 2 4 8 16 32 64 128 256 512 1024
> do
> echo
> echo $x
> time perl xx.pl data.$x > /dev/null
> done
$
我已经调整了输出以提供不同文件大小的实时时间:
1 0m0.022s
2 0m0.005s
4 0m0.007s
8 0m0.013s
16 0m0.035s
32 0m0.130s
64 0m0.523s
128 0m2.035s
256 0m6.756s
512 0m28.062s
1024 1m36.134s
我没有得到核心转储(Mac OS X 10.7.4 上的 Perl 5.16.0;8 GiB 主内存)。它确实开始花费大量时间。当它运行时,它并没有增长;在 1024 行运行期间,它使用了大约 13 MiB 的“真实”内存和 23 MiB 的“虚拟”内存。
我尝试了 Perl 5.10.0(我在我的机器上编译的最旧版本),它使用的“真实”内存略少,基本上相同的“虚拟”内存,而且速度明显较慢(512 行 33.3s;1m 53.9s 1024 行)。
出于比较的目的,我收集了一些放在测试目录中的 C 代码来创建一个大约 88 KiB 的文件,有 3100 行,其中大约 200 行是注释行。相比之下,data.1024 文件的大小约为 77 KiB。处理时间在 10 到 20 毫秒之间。
概括
您拥有的非 C 源代码构成了一个非常讨厌的测试用例。Perl 不应该崩溃。
您使用的是哪个版本的 Perl,在哪个平台上?你的机器有多少内存。但是,内存总量不太可能成为问题(在大多数运行 Perl 的机器上,24 MiB 不是问题)。如果您有一个非常旧的 Perl 版本,结果可能会有所不同。
我还注意到,正则表达式不处理 C 编译器必须处理的一些病态 C 注释,例如:
/\
\
* Yes, this is a comment *\
\
/
/\
\
/ And so is this
是的,您可以拒绝任何提交审查的包含此类评论的代码。