in reply to Re: List::Util's any function
in thread List::Util's any function

Actualy i think you are wrong. ;) Unless my bechmark is way off (which if could be). Any that takes a sub beats the original any and grep hands down everytime. By a rather large margin in fact, and the margin grows substantialy with the size of the data.

use strict; use warnings; use Benchmark qw/cmpthese/; sub any_1 { $_ && return 1 for @_; 0 } sub any_2 { my $code = shift; $code->($_) && return 1 for @_; 0; } my @data; push @data, int rand 50 for 1..100; my @large_data; push @large_data, int rand 50 for 1..10_000; cmpthese(-5, { any_1_small => sub { any_1( map { $_ > 20 } @data); }, any_2_small => sub { any_2( sub { $_ > 20 }, @data); }, grep_small => sub { scalar grep{ $_ > 20 } @data; }, }); cmpthese(-5, { any_1_large => sub { any_1( map { $_ > 20 } @large_data); }, any_2_large => sub { any_2( sub { $_ > 20 }, @large_data); }, grep_large => sub { scalar grep{ $_ > 20 } @large_data; }, }); __END__ Rate any_1_small grep_small any_2_small any_1_small 8962/s -- -84% -96% grep_small 56517/s 531% -- -73% any_2_small 209808/s 2241% 271% -- Rate any_1_large grep_large any_2_large any_1_large 57.3/s -- -90% -99% grep_large 550/s 860% -- -89% any_2_large 5052/s 8723% 819% --

Perhaps I missed your point but it definitly seems that calling a function is better in this case. That is probably because it short circuits quite soon and avoids alot of unneeded workd./me goes to run some tests for when any would fail.

UPDATE:

I benchmarked some more for less matches and no matches.

use strict; use warnings; use Benchmark qw/cmpthese/; sub any_1 { $_ && return 1 for @_; 0 } sub any_2 { my $code = shift; $code->($_) && return 1 for @_; 0; } my @data; push @data, int rand 50 for 1..1000; cmpthese(-5, { any_1_20 => sub { any_1( map { $_ > 20 } @data); }, any_2_20 => sub { any_2( sub { $_ > 20 }, @data); }, grep_20 => sub { scalar grep{ $_ > 20 } @data; }, }); cmpthese(-5, { any_1_45 => sub { any_1( map { $_ > 45 } @data); }, any_2_45 => sub { any_2( sub { $_ > 45 }, @data); }, grep_45 => sub { scalar grep{ $_ > 45 } @data; }, }); cmpthese(-5, { any_1_60 => sub { any_1( map { $_ > 60 } @data); }, any_2_60 => sub { any_2( sub { $_ > 60 }, @data); }, grep_60 => sub { scalar grep{ $_ > 60 } @data; }, }); __END__ Rate any_1_20 grep_20 any_2_20 any_1_20 687/s -- -88% -99% grep_20 5583/s 713% -- -92% any_2_20 72133/s 10400% 1192% -- Rate any_1_45 grep_45 any_2_45 any_1_45 682/s -- -89% -97% grep_45 6013/s 781% -- -75% any_2_45 24282/s 3459% 304% -- Rate any_2_60 any_1_60 grep_60 any_2_60 625/s -- -3% -90% any_1_60 645/s 3% -- -89% grep_60 6017/s 863% 833% --

Grep takes a nice lead when there will be no matche, but any_2 still holds even with any_1, so at worst its only as bad as any_1 and no slower.


___________
Eric Hodges