Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re^5: A locale independent sprintf?

by kcott (Bishop)
on Jul 29, 2020 at 09:05 UTC ( #11119949=note: print w/replies, xml ) Need Help??


in reply to Re^4: A locale independent sprintf?
in thread A locale independent sprintf?

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.

— Ken

Replies are listed 'Best First'.
Re^6: A locale independent sprintf?
by swl (Priest) on Jul 29, 2020 at 12:18 UTC

    I neglected to respond to this point in my other post:

    however, it would seem that if you can live without 'use locale;' that would be a good thing.

    I'm in full agreement here, and don't use it my own code. It's the side effect it being called in another package (Gtk2 in this case) that triggered the issue with my own system.

    salva's recommendation of using no locale in 11119943 and 11119948 looks good to me, and I'll be reaching for it next time I strike this issue.

Re^6: A locale independent sprintf?
by swl (Priest) on Jul 29, 2020 at 11:58 UTC

    The order did switch a little between runs, but that largely ceased once I stopped fiddling about with other processes while the benchmarks were running. I get the same for a locale using a dot as the decimal separator (same WSL system and perl, and also for Strawberry perl 5.28.1). I'll have to try on a native linux machine.

    I'm not sure why your results are so different. The results I showed use a de_DE locale, so perhaps there is overhead when locale handling is triggered. There are also noise effects with benchmarking, although the numbers are pretty distinct in this case. It could also just be my system.

    As for use strict and use warnings, I've been bitten before with string based benchmarking when trying to avoid sub overheads. Taking them out makes no difference to the results (see below, although there is one case where y is faster than s).

    The underlying benchmark code actually calls no strict before it evals code passed as strings. Note the _doeval call in the code generation when a string is passed.

    Results without strict and warnings:

    de_DE.iso88591 3,1 3.1 3.1 Rate y_sprintf s_sprintf sprintf y_sprintf 4515837/s -- -34% -67% s_sprintf 6804054/s 51% -- -50% sprintf 13639660/s 202% 100% -- Rate s_sprintf y_sprintf sprintf s_sprintf 4065578/s -- -14% -64% y_sprintf 4737930/s 17% -- -58% sprintf 11298563/s 178% 138% -- Rate y_sprintf s_sprintf sprintf y_sprintf 4822333/s -- -36% -61% s_sprintf 7501079/s 56% -- -39% sprintf 12255085/s 154% 63% -- Rate y_sprintf s_sprintf sprintf y_sprintf 4712721/s -- -40% -65% s_sprintf 7853825/s 67% -- -42% sprintf 13493133/s 186% 72% -- Rate y_sprintf s_sprintf sprintf y_sprintf 4521907/s -- -33% -66% s_sprintf 6739662/s 49% -- -50% sprintf 13393012/s 196% 99% -- Rate y_sprintf s_sprintf sprintf y_sprintf 4736894/s -- -37% -58% s_sprintf 7546779/s 59% -- -34% sprintf 11352494/s 140% 50% -- Rate y_sprintf s_sprintf sprintf y_sprintf 4954521/s -- -9% -68% s_sprintf 5458237/s 10% -- -64% sprintf 15366383/s 210% 182% -- Rate y_sprintf s_sprintf sprintf y_sprintf 4728476/s -- -33% -65% s_sprintf 7101698/s 50% -- -47% sprintf 13504703/s 186% 90% -- Rate y_sprintf s_sprintf sprintf y_sprintf 4823862/s -- -21% -65% s_sprintf 6083467/s 26% -- -56% sprintf 13732768/s 185% 126% -- Rate y_sprintf s_sprintf sprintf y_sprintf 4290706/s -- -39% -65% s_sprintf 6993552/s 63% -- -42% sprintf 12119185/s 182% 73% --

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11119949]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (6)
As of 2020-10-20 15:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (210 votes). Check out past polls.

    Notices?