use strict; use warnings; use Benchmark 'cmpthese'; my @a = map log, 1..1e6; cmpthese( -2, { 1 => sub {[ map $_ * 4, @a ]}, 2 => sub {[ map $_ / (1/4), @a ]}, }); __END__ Rate 1 2 1 7.70/s -- -27% 2 10.6/s 38% --

Fooling around with integers and floats (inspired by this question: Clean log_10 ?), I found (again!) unknown to me Perl behaviour, which can actually lead to performance issues. Maybe it's open secret and was described 20 years ago. Couldn't come up with good Google query, found nothing, hence this question/observation.

It looks like if scalar contains NV, and though it never has been IV, and another operand is IV, and operator is e.g. multiplication (and some other operators, but not, important, division), then Perl checks if this scalar can be promoted (or is it "demoted"?) to IV, and if so, then result will be IV.

>perl -MDevel::Peek -E "$x=2/1; Dump$x; $y=$x*2; Dump$x; Dump$y" SV = NV(0xd75628) at 0xd75640 REFCNT = 1 FLAGS = (NOK,pNOK) NV = 2 SV = PVNV(0xe26078) at 0xd75640 REFCNT = 1 FLAGS = (IOK,NOK,pIOK,pNOK) IV = 2 NV = 2 PV = 0 SV = IV(0xd75a80) at 0xd75a90 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 4

Though it means some amount of extra work, it could be argued that Perl tries to do "a right thing". However, with arrays, this helpful (?) optimization becomes an anti-DWIM, I think. If array contains just a single element which "looks like integer" (log 1, above), then "optimization" is attempted for all elements. Try range 2..1e6, then there's no penalty. I understand, that (a) as it's said somewhere in FAQ, Perl is not well suited for number crunching, and (b), if properly profiled, difference between multiplication and division by reciprocal somewhere in real program will probably be tiny. Fun fact, nevertheless.


In reply to Should multiplication by integer be avoided in favour of division for performance reasons? by vr

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.