Interesting and surprising results.
You said "the order does switch between runs" but I don't see that in any of the results you posted;
there is quite a substantial fluctuation though (11% to 65%).
I tried with something closer to the code in perlperf to which I linked earlier.
I have Cygwin on Win10. I also have Perlbrew.
I originally ran under 5.32.0; then switched to 5.30.0 to match your version
— there were no significant differences in results.
As my locale uses '.', not ',', I simply swapped the substitution (y/./,/ instead of y/,/./).
Here's the code I used:
#!/usr/bin/env perl
use 5.016;
use warnings;
use Benchmark 'cmpthese';
use POSIX 'locale_h';
say POSIX::setlocale(LC_NUMERIC);
say sprintf('%.2g', 3.14);
say sprintf('%.2g', 3.14) =~ s/\./,/r;
say sprintf('%.2g', 3.14) =~ y/./,/r;
cmpthese 0 => {
sprintf => sub { my $str = sprintf('%.2g', 3.14); return $str; },
y_sprintf => sub { my $str = sprintf('%.2g', 3.14) =~ y/./,/r; ret
+urn $str; },
s_sprintf => sub { my $str = sprintf('%.2g', 3.14) =~ s/\./,/r; re
+turn $str; },
};
Here's a typically result:
$ ./pm_11119934_bench_locale_s_y.pl
en_AU.UTF-8
3.1
3,1
3,1
Rate s_sprintf y_sprintf sprintf
s_sprintf 2940825/s -- -46% -85%
y_sprintf 5493603/s 87% -- -72%
sprintf 19713322/s 570% 259% --
I ran it 5 times with 5.32.0, then 5 times with 5.30.0.
The 87% in the representative run only ranged between 85% and 89% in all runs.
So, I'm getting y/// almost twice as fast as s///;
compared with your s/// being variably faster than y///.
I added in the 'use strict; use warnings;' which you had.
Now the results varied (85% 88% 21% 71% 75%) but 'y_sprintf' was still always faster.
(I suspect the 21% is bogus — perhaps some short-lived background process fired up at that time.)
I then added the 'use locale;' that you had and this substantially slowed down processing:
'y_sprintf' was still faster than 's_sprintf' but I wouldn't say significantly so (5% 1% 7% 12% 8%).
I next replaced my subs with your strings (',' and '.' swapped as before).
Again, 'y_sprintf' was faster and this time closer to, albeit more spread out than, my original results (75% 89% 87% 92% 90%).
So, I can't replicate your s/// being faster than y///;
all my tests indicated that the opposite was the case.
I think the addition of 'use strict; use warnings;' was probably unnecessary for the benchmark;
and perhaps a distraction.
I don't know enough about locales to confidently comment;
however, it would seem that if you can live without 'use locale;' that would be a good thing
(its doco, locale, has warnings about its use).
Perhaps try with some of my variations to see if you get different results.
|