in reply to Re: A locale independent sprintf?
in thread A locale independent sprintf?
Thanks Rob.
I was using that strategy in my code, but it incurs sub overheads and profiling showed my uses were in a fairly hot path for large data sets. (It could also just another example of me micro-optimising, though).
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^3: A locale independent sprintf?
by kcott (Archbishop) on Jul 29, 2020 at 03:37 UTC | |
Using y/,/./, instead of s/,/./, should be faster (see "perlperf: Search and replace or tr"). Obviously, I can't say whether it will be noticeably or usefully faster. You may want the 'r' modifier. Here's a somewhat fudged example for demonstration purposes:
If you try this, I'd be interested in what sort of speed improvement you see. — Ken | [reply] [d/l] [select] |
by swl (Parson) on Jul 29, 2020 at 04:06 UTC | |
Good point. I'll see if I can set up some benchmarking and post the results. Update: Running the code below under ubuntu bash under windows with LC_NUMERIC set to de_DE.iso88591 indicates that s///r is about 20% faster than y//r. Both are in the order of millions per second, though. And as yet another update, the order does switch between runs so it's not a consistent outcome. Results:
Code:
(post was further updated to distinguish results from code) | [reply] [d/l] [select] |
by kcott (Archbishop) on Jul 29, 2020 at 09:05 UTC | |
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:
Here's a typically result:
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 | [reply] [d/l] [select] |
by swl (Parson) on Jul 29, 2020 at 12:18 UTC | |
by swl (Parson) on Jul 29, 2020 at 11:58 UTC | |
by swl (Parson) on Jul 29, 2020 at 05:11 UTC | |
Some extra runs while not interacting with the machine. Perl is 5.30.0 via perlbrew under WSL.
Results:
| [reply] [d/l] [select] |