Хитрость в этих вещах заключается в том, чтобы знать ваши другие ограничения.Как часто вам нужно будет делать это в вашей программе и насколько велика эта строка?С одним выстрелом короткой струны, вы можете уйти с отходами.Если вам придется делать это многократно или для больших строк, это будет иметь гораздо большее значение.
Я проверяю это в течение 5 секунд CPU (Mac Pro, OS X.6.8, Perl 5.14.1) для увеличения порядкаВеличина в длине строки:
+-------------------------------------------------+
| Iterations |
+-----------------+---------+---------+---------+---------+---------+
| Sub name | 10**1 | 10**2 | 10**3 | 10**4 | 10**5 |
+-----------------+---------+---------+---------+---------+---------+
| iterate_foreach | 983840 | 141997 | 16333 | 1686 | 168 |
| iterate_for | 1041713 | 146608 | 15370 | 1538 | 155 |
| sorter | 1194656 | 120608 | 10490 | 888 | 82 |
| maxstr | 1505280 | 180923 | 19764 | 2120 | 202 |
| control | 8019246 | 8019246 | 7719377 | 5041132 | 710027 |
+-----------------+---------+---------+---------+---------+---------+
List :: Util's maxstr
доминирует во всех случаях.Для первого порядка, строка из 10 символов, sorter
нормально.После этого sorter
становится все хуже и хуже, как и следовало ожидать.iterate_foreach
и iterate_for
ухудшаются намного лучше.
Код:
use 5.010;
use strict;
use warnings;
use Benchmark;
use List::Util;
my $count = -5;
foreach my $order ( 1 .. 5 ) {
say "-" x 50, "\nTiming for order $order";
my $string = make_string( $order );
timethese( $count, {
'sorter' => sub { my $c = sorter( $string ) },
'maxstr' => sub { my $c = maxstr( $string ) },
'iterate_for' => sub { my $c = iterate_for( $string ) },
'iterate_foreach' => sub { my $c = iterate_foreach( $string ) },
'control' => sub { my $c = control( $string ) },
});
}
sub make_string {
my $order = shift;
my $string;
for( my $i = 0; $i < 10**$order; $i++ ) {
$string .= chr int rand 256;
}
$string;
}
sub sorter {
my $str = shift;
my $char = (sort split //, $str)[-1];
}
sub maxstr {
my $str = shift;
my $char = List::Util::maxstr( split //, $str );
}
sub iterate_for {
my $str = shift;
my $length = length $str;
my $max = '';
for( my $i = 0; $i < $length; $i++ ){
my $chr = substr( $str, $i, 1 );
$max = $chr if $chr gt $max;
}
return $max;
}
sub iterate_foreach {
my $str = shift;
my $max = '';
foreach ( split //, $str ){
$max = $_ if $_ gt $max;
}
return $max;
}
sub control {
my $str = shift;
return 'a';
}