我有一些代码,在一个部分将执行很多,而我是wondernig哪个方式是一个更有效的实现。我将使用for循环来模拟执行的部分:
选项A:
my %sections = (
'somestring1' => 1,
'somestring2' => 1,
'somestring3' => 1,
'somestring4' => 1
);
for (0..10000)
{
# $element is chosen at random
$namespace = $element if $sections{$element};
}
选项B:
for (0..10000)
{
# $element is chosen at random
$namespace = $element if ($element eq'somestring1' ||
$element eq'somestring2' ||
$element eq'somestring3' ||
$element eq'somestring4');
}
任何人都可以对此进行基准测试或知道答案,因为我不熟悉基准测试工具。
这段代码在这种情况下可能没有意义,但实际上我需要使用它。
答案 0 :(得分:17)
使用Benchmark模块中的cmpthese
功能
use strict;
use warnings;
use Benchmark qw'cmpthese';
my %sections = (
somestring1 => 1,
somestring2 => 1,
somestring3 => 1,
somestring4 => 1
);
my @elements = map { 'somestring' . int(1 + rand(10)) } 1 .. 100;
my $namespace;
cmpthese(100000, {
hash_value => sub {
foreach my $element (@elements) {
$namespace = $element if $sections{$element};
}
},
hash_exists => sub {
foreach my $element (@elements) {
$namespace = $element if exists $sections{$element};
}
},
string_cmp => sub {
foreach my $element (@elements) {
$namespace = $element if (
$element eq'somestring1' ||
$element eq'somestring2' ||
$element eq'somestring3' ||
$element eq'somestring4');
}
},
});
我的结果(在WinXP上运行Perl 5.10):
Rate string_cmp hash_value hash_exists
string_cmp 18932/s -- -44% -50%
hash_value 33512/s 77% -- -12%
hash_exists 38095/s 101% 14% --
因此哈希查找比级联字符串比较快77%,并且检查哈希存在而不是值(如Adam Bellaire建议的那样)仍然快14%。
答案 1 :(得分:5)
我的猜测是,exists
的第一个版本会更快,更不用说更易读和可维护了。
for (0..10000)
{
# $element is chosen at random
$namespace = $element if exists $sections{$element};
}
仅仅检查是否存在散列键比检索其值进行比较更快,因此请使用exists
。
答案 2 :(得分:4)
哈希查找机制要快得多。
答案 3 :(得分:3)
这可能是熟悉基准测试工具的时候了,比如CPAN模块Benchmark。
答案 4 :(得分:0)
迈克尔卡曼的基准测试很好,但结果现在已经很老了,所以不在自己的机器上运行它的人可能会得到错误的想法。 因此,在具有Mac OS X和Perl 5.24.1的Mac Pro上完全相同的基准测试(仅提高10倍的情况以提供更一致的结果):
Rate string_cmp hash_exists hash_value
string_cmp 54142/s -- -28% -32%
hash_exists 74850/s 38% -- -7%
hash_value 80192/s 48% 7% --
但是,在使用CentOS 7 / Perl 5.24.0的AWS上,我们得到:
string_cmp 70373/s -- -24% -25%
hash_value 92851/s 32% -- -1%
hash_exists 93545/s 33% 1% --
所以,我会说测试你自己的机器,但是现有的似乎没有提供好处(在我的Mac上使用最新的Perl,它在这个特定的测试中甚至可以慢得多 - 甚至在其他测试中也是如此)。 / p>
我不喜欢基准测试的一件事是它相当随意地选择将4个等式与哈希检查进行比较。不要混淆,如果我们在哈希中只有一个项目,那么我们比较一下我们获得的单一相等性(在我的Mac Pro / Perl 5.24.1上):
hash_value 119474/s -- -1% -14% -34%
hash_exists 121065/s 1% -- -12% -33%
grep 138122/s 16% 14% -- -23%
string_cmp 180180/s 51% 49% 30% --
我在那里扔了一个grep,它避免了foreach循环的比较。因此,单个相等显然比散列检查更快,但速度不会快两倍,因此如果您可以使用散列检查替换两个相等,则可以获得一个好处:
string_cmp 104167/s -- -15% -17%
hash_value 121951/s 17% -- -2%
hash_exists 125000/s 20% 2% --
但是,这是在循环外部预先构建的哈希,就像在原始示例中一样。如果我们在每个基准周期创建哈希怎么办?即你想要检查数组中是否存在一些值,是否值得创建哈希的开销?我不会给你带来更多的结果,因为你可能会发现它们在你的机器上有所不同,但答案是2个值“它取决于”(所以也许你不应该打扰),但对于3个或更多你应该做它