Perl中while(each)和foreach之间的性能差异

vin*_*nod 3 perl foreach

我测试的哈希包含大约70000所大学,每所大学包含大约20名学生.我尝试了5次,结果如下.foreach性能和(每个)性能有很大差异.为什么会这样?

带while循环的代码:

while ( my ($college_code, $college_info_hr) = each (%{$college_data_hr}) ) {
    while ( my ($student_num, $student_info_hr) = each (%{$college_info_hr->{'students'}}) ) {
        if($student_num < 104000) { ## Delete the info of students before 2004.
            delete $college_info_hr->{'students'}{$student_num};
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用foreach循环的代码:

foreach my $college_code (keys %{$college_data_hr}) {
    foreach my $student_num (keys %{$college_data_hr->{$college_code}{'students'}}) {
        if($student_num < 104000) { ## Delete the info of students before 2004.
            delete $college_data_hr->{$college_code}{'students'}{$student_num};
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当大学数量为70,000时,执行时间为:

对于带while循环的代码(Interval time以秒为单位):

间隔时间:2.186621

间隔时间:2.058644

间隔时间:2.055645

间隔时间:2.101637

间隔时间:2.124632

对于带有foreach循环的代码:(间隔时间以秒为单位)

间隔时间:1.341768

间隔时间:1.436751

间隔时间:1.346529

间隔时间:1.302775

间隔时间:1.356765

当大学数量为248,000时,执行时间为:

(while循环的执行时间)

间隔时间:9.084427

间隔时间:8.438684

间隔时间:9.329338

间隔时间:9.169687

(foreach循环的执行时间)

间隔时间:5.502048

间隔时间:6.386692

间隔时间:5.596032

间隔时间:5.620144

tob*_*ink 7

foreach版本仅对$college_data_hr->{$college_code}{'students'}每个大学一次取消引用hashref,因此比while每个学生需要执行一次的版本更快.

foreach版本可能会使用更多内存,因为它需要构建包含每个哈希键的临时列表.

Data :: Alias可以帮助您加速while解决方案.我没有对此进行基准测试,但它应该相当快......

use Data::Alias;

while ( my ($college_code, $college_info_hr) = each %$college_data_hr ) {
    alias ( my %students = %{$college_info_hr->{'students'}} );
    while ( my ($student_num, $student_info_hr) = each %students ) {
        if ($student_num < 104000) { ## Delete the info of students before 2004.
            delete $students{$student_num};
        }
    }
}
Run Code Online (Sandbox Code Playgroud)