SUBSTR() with replacement or lvalue performance issues

Discussion in 'Perl Misc' started by sln@netherlands.com, Nov 7, 2008.

  1. Guest

    I've read the docs on substr many a times but I still am not
    quite clear on if being used as a lvalue or the replacement parameter.

    I have a possible quite large string (could be megabytes).
    I wan't to insert, possible in the middle a replacement text.
    I'm running through an itteration on the string throught sub's etc.

    Apart from like, copy from the start of a matched position, to a
    file (as opposed to another buffer), then catenating the modification
    to the file, then continue on with the next match, is the substr
    (lvalue or replacement) a viable option?

    I have to consider performance on such large operations.

    What do you think would be the performance 'hit' if modifying
    the string in-place using substr as either an lvalue or replacement?

    There has to be some memcpy()'s or moves involved.
    If replacement based, I can adjust the pos() for the next match,
    but to insert even a little change in string size, in the middle
    of a very large string could be a big performance hit?

    All help is appretiated!
    TIA

    sln
    , Nov 7, 2008
    #1
    1. Advertising

  2. Guest

    wrote:
    > I've read the docs on substr many a times but I still am not
    > quite clear on if being used as a lvalue or the replacement parameter.
    >
    > I have a possible quite large string (could be megabytes).
    > I wan't to insert, possible in the middle a replacement text.
    > I'm running through an itteration on the string throught sub's etc.
    >
    > Apart from like, copy from the start of a matched position, to a
    > file (as opposed to another buffer), then catenating the modification
    > to the file, then continue on with the next match,


    Are you describing just the ordinary practice if writing your output to
    an output file while looping over a read of the input file? That is
    often a good way to do things.

    > is the substr
    > (lvalue or replacement) a viable option?
    >
    > I have to consider performance on such large operations.
    >
    > What do you think would be the performance 'hit' if modifying
    > the string in-place using substr as either an lvalue or replacement?


    On my system it takes a little under a second to use substr to splice
    into the middle of a 1GB string (in a way that makes the string longer)

    ##baseline:
    time perl -le 'my $x; $x.="x"x1000 foreach 1..1e6; \
    substr $x, 4e8, 3, "yyyy" foreach 1..0 ;'
    1.352u 0.904s 0:02.29 98.2% 0+0k 0+0io 0pf+0w

    ##20 substrs
    time perl -le 'my $x; $x.="x"x1000 foreach 1..1e6; \
    substr $x, 4e8, 3, "yyyy" foreach 1..0 ;'
    16.585u 1.084s 0:18.31 96.4% 0+0k 0+0io 0pf+0w

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Nov 7, 2008
    #2
    1. Advertising

  3. Guest

    On 07 Nov 2008 03:22:43 GMT, wrote:

    > wrote:
    >> I've read the docs on substr many a times but I still am not
    >> quite clear on if being used as a lvalue or the replacement parameter.
    >>
    >> I have a possible quite large string (could be megabytes).
    >> I wan't to insert, possible in the middle a replacement text.
    >> I'm running through an itteration on the string throught sub's etc.
    >>
    >> Apart from like, copy from the start of a matched position, to a
    >> file (as opposed to another buffer), then catenating the modification
    >> to the file, then continue on with the next match,

    >
    >Are you describing just the ordinary practice if writing your output to
    >an output file while looping over a read of the input file? That is
    >often a good way to do things.
    >

    [snip]

    Yes. I'm looking at your benchmarks for substr(). I have nightmares on
    if threre are like over 100,000 replacements in a gigantic string which
    could easily happen. There is a block replacement, I'm not doing s///g
    on a gigantic string. I'm finding a block, then acting on indirect values,
    then re-inserting them in the stream. Regexp has stopped, to be re'pos()
    later (or not). Depends on if a seperate file is being constructed or
    the replacement is acting strictly on the buffer.

    I'm looking over you benches. I have a bad feeling though. Insertion
    (or deletion) several hundred thousand possible times could reek havoc
    maybe.

    Checking... thanks!

    sln

    >> is the substr
    >> (lvalue or replacement) a viable option?
    >>
    >> I have to consider performance on such large operations.
    >>
    >> What do you think would be the performance 'hit' if modifying
    >> the string in-place using substr as either an lvalue or replacement?

    >
    >On my system it takes a little under a second to use substr to splice
    >into the middle of a 1GB string (in a way that makes the string longer)
    >
    >##baseline:
    >time perl -le 'my $x; $x.="x"x1000 foreach 1..1e6; \
    > substr $x, 4e8, 3, "yyyy" foreach 1..0 ;'
    >1.352u 0.904s 0:02.29 98.2% 0+0k 0+0io 0pf+0w
    >
    >##20 substrs
    >time perl -le 'my $x; $x.="x"x1000 foreach 1..1e6; \
    > substr $x, 4e8, 3, "yyyy" foreach 1..0 ;'
    >16.585u 1.084s 0:18.31 96.4% 0+0k 0+0io 0pf+0w
    >
    >Xho
    , Nov 7, 2008
    #3
  4. On Fri, 07 Nov 2008 02:17:58 GMT, wrote:

    >Apart from like, copy from the start of a matched position, to a
    >file (as opposed to another buffer), then catenating the modification
    >to the file, then continue on with the next match, is the substr
    >(lvalue or replacement) a viable option?
    >
    >I have to consider performance on such large operations.


    ISTR that the lvaluedness of substr()'s return value, as long as the
    fact that you can EVEN take references of it and modify the string
    with a sort of action-at-distance was put there specifically for
    performance issues. At some point there were problems with
    substitutions having a lenght larger than the substituted IalsoIRC,
    but they should be solved in recent enough perls.

    See: <http://perlmonks.org/?node_id=498434>


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
    Michele Dondi, Nov 7, 2008
    #4
  5. smallpond Guest

    On Nov 7, 12:48 am, wrote:
    >
    > I'm looking over you benches. I have a bad feeling though. Insertion
    > (or deletion) several hundred thousand possible times could reek havoc
    > maybe.
    >



    code can reek, but havoc must be wreaked.

    It is good practice to see if you actually have a problem before doing
    optimization. "First make it right, then make it fast."
    smallpond, Nov 7, 2008
    #5
  6. Mirco Wahab Guest

    wrote:
    > Yes. I'm looking at your benchmarks for substr(). I have nightmares on
    > if threre are like over 100,000 replacements in a gigantic string which
    > could easily happen. There is a block replacement, I'm not doing s///g
    > on a gigantic string. I'm finding a block, then acting on indirect values,
    > then re-inserting them in the stream. Regexp has stopped, to be re'pos()
    > later (or not). Depends on if a seperate file is being constructed or
    > the replacement is acting strictly on the buffer.


    What is the problem domain? "Megabyte strings" and
    "100,000 things" to might not turn out that slow on
    a usual 3GHz Core2 that has 6MB L2 available.

    > I'm looking over you benches. I have a bad feeling though. Insertion
    > (or deletion) several hundred thousand possible times could reek havoc
    > maybe.


    A 'left value'-substr() might be beaten by an
    "Inline C" based use of memchr/memcpy - that
    unfortunately would need to handle the reallocation
    of the buffer manually (if possible/feasible at
    all in your problem range).

    Regards

    M.
    Mirco Wahab, Nov 7, 2008
    #6
  7. Guest

    Michele Dondi <> wrote:
    > On Fri, 07 Nov 2008 02:17:58 GMT, wrote:
    >
    > >Apart from like, copy from the start of a matched position, to a
    > >file (as opposed to another buffer), then catenating the modification
    > >to the file, then continue on with the next match, is the substr
    > >(lvalue or replacement) a viable option?
    > >
    > >I have to consider performance on such large operations.

    >
    > ISTR that the lvaluedness of substr()'s return value, as long as the
    > fact that you can EVEN take references of it and modify the string
    > with a sort of action-at-distance was put there specifically for
    > performance issues. At some point there were problems with
    > substitutions having a lenght larger than the substituted IalsoIRC,
    > but they should be solved in recent enough perls.
    >
    > See: <http://perlmonks.org/?node_id=498434>


    My reading of that is there used to be problems having more than one
    action-at-distance references outstanding on the same string, regardless
    of the size of the replacements.

    Doing replacements that don't preserve length can have a performance
    impact, but I don't see that as a "problem" in the same way a bug is a
    "problem"; just as one of the trade-offs that always exist and which need
    to be kept in mind. I doubt this performance issue will be "fixed" anytime
    soon, as it would likely require a fundamental change of the way strings
    are managed (i.e. as ropes rather than as contiguous memory regions.)

    Of course, the other issue is one of semantics. If I take reference like
    my $x=\substr($q,100,10), and then later do an insertion like
    substr($q,10,0,"xxx"), will $x now refer to the same *characters* as it did
    before (i.e. substr($q,103,10)) or to the same *positions* as it did
    before. Empirically, it refers to the same positions.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Nov 7, 2008
    #7
  8. Guest

    On Fri, 07 Nov 2008 11:41:21 +0100, Michele Dondi <> wrote:

    >On Fri, 07 Nov 2008 02:17:58 GMT, wrote:
    >
    >>Apart from like, copy from the start of a matched position, to a
    >>file (as opposed to another buffer), then catenating the modification
    >>to the file, then continue on with the next match, is the substr
    >>(lvalue or replacement) a viable option?
    >>
    >>I have to consider performance on such large operations.

    >
    >ISTR that the lvaluedness of substr()'s return value, as long as the
    >fact that you can EVEN take references of it and modify the string
    >with a sort of action-at-distance was put there specifically for
    >performance issues. At some point there were problems with
    >substitutions having a lenght larger than the substituted IalsoIRC,
    >but they should be solved in recent enough perls.
    >
    >See: <http://perlmonks.org/?node_id=498434>
    >
    >
    >Michele


    If c, place a 0 at the start of find, save pointer to begin of
    last find, add ptr to list.
    Create a new char[modified size], add ptr to list
    Repeat until end of string.

    Write pointer list to file/buffer (file).
    Delete list of ptrs.

    Perl can't do reference mid string. Jimmy jack it maybe..

    sln
    , Nov 9, 2008
    #8
  9. Guest

    On Fri, 07 Nov 2008 11:41:21 +0100, Michele Dondi <> wrote:

    >On Fri, 07 Nov 2008 02:17:58 GMT, wrote:
    >
    >>Apart from like, copy from the start of a matched position, to a
    >>file (as opposed to another buffer), then catenating the modification
    >>to the file, then continue on with the next match, is the substr
    >>(lvalue or replacement) a viable option?
    >>
    >>I have to consider performance on such large operations.

    >
    >ISTR that the lvaluedness of substr()'s return value, as long as the
    >fact that you can EVEN take references of it and modify the string
    >with a sort of action-at-distance was put there specifically for
    >performance issues. At some point there were problems with
    >substitutions having a lenght larger than the substituted IalsoIRC,
    >but they should be solved in recent enough perls.
    >
    >See: <http://perlmonks.org/?node_id=498434>
    >
    >
    >Michele


    ^^^^^^^^^^^^

    Being able to get segment references while not altering the
    string works pretty good. Altering the string with the ref's is
    possible but I wouldn't trust it and the string would still shrink/expand.

    In the simplest example usage, something like below would seem to solve
    performance issues. Thanks for the link!


    sln
    ---------------------------------

    use strict;
    use warnings;

    my $bigstring = \"some big big big scalar string";
    my $modstring;
    my $lastpos = 0;
    my @segrefs = ();

    while ($$bigstring =~ /big/g)
    {
    my ($offset, $curpos) = ($-[0], pos($$bigstring));

    # modify part (local copy) of the big string
    $modstring = substr $$bigstring, $offset, ($curpos - $offset);
    $modstring .= "-huge";

    # cache the interval (read only) and modstring references
    push @segrefs, \substr $$bigstring, $lastpos, ($offset - $lastpos);
    push @segrefs, \$modstring;

    $lastpos = $curpos;
    }

    # print the new string (to a file maybe)

    if ($lastpos)
    {
    push @segrefs, \substr $$bigstring, $lastpos;
    for (@segrefs) {
    print $$_;
    }
    }
    , Nov 10, 2008
    #9
  10. [A complimentary Cc of this posting was NOT [per weedlist] sent to
    Michele Dondi
    <>], who wrote in article <>:
    > ISTR that the lvaluedness of substr()'s return value, as long as the
    > fact that you can EVEN take references of it and modify the string
    > with a sort of action-at-distance was put there specifically for
    > performance issues. At some point there were problems with
    > substitutions having a lenght larger than the substituted IalsoIRC,
    > but they should be solved in recent enough perls.
    >
    > See: <http://perlmonks.org/?node_id=498434>


    Simple experiments show that it is still buggy with 5.8.8: code below returns

    the quick brown fox jumps over the laxy dog
    the quick brown fox jumps over the lazy dog

    Hope this helps,
    Ilya

    #!/usr/bin/perl -w
    use strict;

    my $bigScalar = 'the quick brown fox jumps over the laxy dog';

    sub change_nth ($$@) {
    my($n, $subst) = (shift, shift);
    $_[$n] = $subst;
    return; # Just in case: avoid $_[7] being returned
    }

    change_nth 7, 'lazy', map{ substr $bigScalar, $_->[0], $_->[1] }
    [0,3], [4,5], [10,5], [16,3], [20,5], [26,4], [31,3], [35,4], [40,3];
    print "$bigScalar\n";

    change_nth 1, 'lazy', substr($bigScalar, 31, 3), substr($bigScalar, 35, 4),
    substr($bigScalar, 40, 3);
    print "$bigScalar\n";
    __END__
    Ilya Zakharevich, Nov 10, 2008
    #10
  11. On Mon, 10 Nov 2008 23:44:51 +0000 (UTC), Ilya Zakharevich
    <> wrote:

    >> See: <http://perlmonks.org/?node_id=498434>

    >
    >Simple experiments show that it is still buggy with 5.8.8: code below returns
    >
    > the quick brown fox jumps over the laxy dog
    > the quick brown fox jumps over the lazy dog


    Same with 5.10 here.


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
    Michele Dondi, Nov 11, 2008
    #11
  12. Guest

    Ilya Zakharevich <> wrote:
    > [A complimentary Cc of this posting was NOT [per weedlist] sent to
    > Michele Dondi
    > <>], who wrote in article
    > <>:
    > > ISTR that the lvaluedness of substr()'s return value, as long as the
    > > fact that you can EVEN take references of it and modify the string
    > > with a sort of action-at-distance was put there specifically for
    > > performance issues. At some point there were problems with
    > > substitutions having a lenght larger than the substituted IalsoIRC,
    > > but they should be solved in recent enough perls.
    > >
    > > See: <http://perlmonks.org/?node_id=498434>

    >
    > Simple experiments show that it is still buggy with 5.8.8: code below
    > returns
    >

    ....
    >
    >
    > change_nth 7, 'lazy', map{ substr $bigScalar, $_->[0], $_->[1] }
    > [0,3], [4,5], [10,5], [16,3], [20,5], [26,4], [31,3], [35,4], [40,3];
    > print "$bigScalar\n";


    I don't see this as a bug with substr. "Map" doesn't alias the values
    it returns, it copies them. So the magic is no longer there, just as it
    isn't present in $x if you do:
    my $x=substr $bigScalar, 1, 4;

    So if it's a bug, it is a bug with map, not substr.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Nov 11, 2008
    #12
  13. Guest

    On 11 Nov 2008 17:14:06 GMT, wrote:

    >Ilya Zakharevich <> wrote:
    >> [A complimentary Cc of this posting was NOT [per weedlist] sent to
    >> Michele Dondi
    >> <>], who wrote in article
    >> <>:
    >> > ISTR that the lvaluedness of substr()'s return value, as long as the
    >> > fact that you can EVEN take references of it and modify the string
    >> > with a sort of action-at-distance was put there specifically for
    >> > performance issues. At some point there were problems with
    >> > substitutions having a lenght larger than the substituted IalsoIRC,
    >> > but they should be solved in recent enough perls.
    >> >
    >> > See: <http://perlmonks.org/?node_id=498434>

    >>
    >> Simple experiments show that it is still buggy with 5.8.8: code below
    >> returns
    >>

    >...
    >>
    >>
    >> change_nth 7, 'lazy', map{ substr $bigScalar, $_->[0], $_->[1] }

    ^
    \


    >> [0,3], [4,5], [10,5], [16,3], [20,5], [26,4], [31,3], [35,4], [40,3];
    >> print "$bigScalar\n";

    >
    >I don't see this as a bug with substr. "Map" doesn't alias the values
    >it returns, it copies them. So the magic is no longer there, just as it
    >isn't present in $x if you do:
    >my $x=substr $bigScalar, 1, 4;
    >
    >So if it's a bug, it is a bug with map, not substr.
    >
    >Xho
    , Nov 11, 2008
    #13
  14. [A complimentary Cc of this posting was sent to
    <>], who wrote in article <>:
    > >> Simple experiments show that it is still buggy with 5.8.8: code below
    > >> returns


    > >> change_nth 7, 'lazy', map{ substr $bigScalar, $_->[0], $_->[1] }

    > ^
    > \


    Nope.

    Hope this helps,
    Ilya
    Ilya Zakharevich, Nov 11, 2008
    #14
  15. [A complimentary Cc of this posting was sent to

    <>], who wrote in article <20081111121442.793$>:
    > > Simple experiments show that it is still buggy with 5.8.8: code below
    > > returns


    > > change_nth 7, 'lazy', map{ substr $bigScalar, $_->[0], $_->[1] }
    > > [0,3], [4,5], [10,5], [16,3], [20,5], [26,4], [31,3], [35,4], [40,3];
    > > print "$bigScalar\n";


    > I don't see this as a bug with substr.


    It is a bug, and it involves substr. ;-)

    > "Map" doesn't alias the values it returns, it copies them.


    What for? Why this should not work:

    perl -wle "@a=(10..15); sub z2{$_[2]=0}; z2 map $_, @a; print for @a"

    Thanks,
    Ilya
    Ilya Zakharevich, Nov 11, 2008
    #15
  16. Guest

    Ilya Zakharevich <> wrote:
    > [A complimentary Cc of this posting was sent to
    > <>], who wrote in article
    > <>:
    > > >> Simple experiments show that it is still buggy with 5.8.8: code
    > > >> below returns

    >
    > > >> change_nth 7, 'lazy', map{ substr $bigScalar, $_->[0], $_->[1] }

    > > ^
    > > \

    >
    > Nope.


    It will work provided you make the obvious change to change_nth to do the
    dereference.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Nov 11, 2008
    #16
  17. Guest

    On Fri, 07 Nov 2008 11:41:21 +0100, Michele Dondi <> wrote:

    >On Fri, 07 Nov 2008 02:17:58 GMT, wrote:
    >
    >>Apart from like, copy from the start of a matched position, to a
    >>file (as opposed to another buffer), then catenating the modification
    >>to the file, then continue on with the next match, is the substr
    >>(lvalue or replacement) a viable option?
    >>
    >>I have to consider performance on such large operations.

    >
    >ISTR that the lvaluedness of substr()'s return value, as long as the
    >fact that you can EVEN take references of it and modify the string
    >with a sort of action-at-distance was put there specifically for
    >performance issues. At some point there were problems with
    >substitutions having a lenght larger than the substituted IalsoIRC,
    >but they should be solved in recent enough perls.
    >
    >See: <http://perlmonks.org/?node_id=498434>
    >
    >
    >Michele


    5.8.6 has problems:

    use strict;
    use warnings;

    my $cnt;

    printf "\nPerl Version: %vd\n", $^V;
    my @fldvals = split( ' ', "one two three four five");

    ## Initalize references on dummy record
    ## -------------------------------------
    print "\nInit \@lvrefs to 5 char fields x 7 fields/record\n",'-'x30,"\n";

    my $bigscalar = "+++++-----+++++-----+++++-----+++++";
    my @lvrefs = map{ \substr $bigscalar, $_->[0], $_->[1] }
    [0,5], [5,5], [10,5], [15,5], [20,5], [25,5], [30,5];
    print "\nrecord: <".$bigscalar.">\n\n";
    $cnt = 1;
    print " field ".$cnt++." \t<".$$_.">\n" for @lvrefs;

    ## Change record, print $$lvrefs
    ## -------------------------------------
    print "\nChange record, print \$\$lvrefs\n",'-'x30,"\n";

    # Set bigscalar to 6 char width fields, use @lvrefs to print
    $bigscalar = sprintf ("%-6s"x5, @fldvals);
    print "\n(\%-6s) record: <".$bigscalar.">\n\n";
    $cnt = 1;
    print " field ".$cnt++." \t<".$$_.">\n" for @lvrefs;

    # Set bigscalar to 5 char width fields, use @lvrefs to print
    $bigscalar = sprintf ("%-5s"x5, @fldvals);
    print "\n(\%-5s) record: <".$bigscalar.">\n\n";
    $cnt = 1;
    print " field ".$cnt++." \t<".$$_.">\n" for @lvrefs;

    ## Assign to $$lvrefs, print record
    ## -------------------------------------
    print "\nAssign to \$\$lvrefs, print record\n",'-'x30,"\n";

    # Assign $$lvref to 10 char value's
    print "\n(\%-10s) \$\$lvrefs\n\n";
    $cnt = 0;
    for (@fldvals)
    { ${$lvrefs[$cnt++]} = sprintf "%-10s", $_; }
    $cnt = 1;
    print " field ".$cnt++." \t<".$$_.">\n" for @lvrefs;
    print "\nrecord: <".$bigscalar.">\n";

    # Assign $$lvref to 5 char value's
    print "\n(\%-5s) \$\$lvrefs\n\n";
    $cnt = 0;
    for (@fldvals)
    { ${$lvrefs[$cnt++]} = sprintf "%-5s", $_; }
    $cnt = 1;
    print " field ".$cnt++." \t<".$$_.">\n" for @lvrefs;
    print "\nrecord: <".$bigscalar.">\n";

    # Assign $$lvref to 2 char value's
    print "\n(\%-2d, 1..7) \$\$lvrefs\n\n";
    $cnt = 0;
    for (1..7)
    { ${$lvrefs[$cnt++]} = sprintf "%-2d", $_; }
    $cnt = 1;
    print " field ".$cnt++." \t<".$$_.">\n" for @lvrefs;
    print "\nrecord: <".$bigscalar.">\n";

    __END__


    Perl Version: 5.8.6

    Init @lvrefs to 5 char fields x 7 fields/record
    ------------------------------

    record: <+++++-----+++++-----+++++-----+++++>

    field 1 <+++++>
    field 2 <----->
    field 3 <+++++>
    field 4 <----->
    field 5 <+++++>
    field 6 <----->
    field 7 <+++++>

    Change record, print $$lvrefs
    ------------------------------

    (%-6s) record: <one two three four five >

    field 1 <one >
    field 2 < two >
    field 3 < thr>
    field 4 <ee fo>
    field 5 <ur f>
    field 6 <ive >
    field 7 <>

    (%-5s) record: <one two threefour five >

    field 1 <one >
    field 2 <two >
    field 3 <three>
    field 4 <four >
    field 5 <five >
    field 6 <>
    field 7 <>

    Assign to $$lvrefs, print record
    ------------------------------

    (%-10s) $$lvrefs

    field 1 <one >
    field 2 <two >
    field 3 <three>
    field 4 <four >
    field 5 <five >
    field 6 < >
    field 7 <two >

    record: <one two threefour five two threefour five >

    (%-5s) $$lvrefs

    field 1 <one >
    field 2 <two >
    field 3 <three>
    field 4 <four >
    field 5 <five >
    field 6 < >
    field 7 <two >

    record: <one two threefour five two threefour five >

    (%-2d, 1..7) $$lvrefs

    field 1 <1 two>
    field 2 <2 eef>
    field 3 <3 ive>
    field 4 <4 tw>
    field 5 <5 ree>
    field 6 <6 fiv>
    field 7 <7 >

    record: <1 two2 eef3 ive4 tw5 ree6 fiv7 >
    , Nov 11, 2008
    #17
  18. Guest

    Ilya Zakharevich <> wrote:
    > [A complimentary Cc of this posting was sent to
    >


    > > "Map" doesn't alias the values it returns, it copies them.

    >
    > What for? Why this should not work:
    >
    > perl -wle "@a=(10..15); sub z2{$_[2]=0}; z2 map $_, @a; print for @a"


    It does work. It just doesn't do what you want :)

    I think the current behavior is reasonable, although it would be nice to
    have the other as an option (maybe Array::Splice could have a map_alias,
    even though it is getting a bit far afield of the name-space).

    The current behavior is consistent with what other things that conceptually
    *could* keep aliasing, but don't. Like push. Or subroutines.

    perl -le ' my @x=1..10; sub foo { $_[0]}; foreach (@x) {
    $_="x" foreach foo($_)}; print "@x"'
    1 2 3 4 5 6 7 8 9 10

    Well, subroutines that have not been declared :lvalue, anyway.

    On the other hand, reverse does preserve aliasing.

    a do block also preserves aliasing, but for some odd reason I'm not
    allowed to assign to one directly.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Nov 11, 2008
    #18
  19. Guest

    wrote:
    > On Fri, 07 Nov 2008 11:41:21 +0100, Michele Dondi
    > <> wrote:
    >
    > >On Fri, 07 Nov 2008 02:17:58 GMT, wrote:
    > >
    > >>Apart from like, copy from the start of a matched position, to a
    > >>file (as opposed to another buffer), then catenating the modification
    > >>to the file, then continue on with the next match, is the substr
    > >>(lvalue or replacement) a viable option?
    > >>
    > >>I have to consider performance on such large operations.

    > >
    > >ISTR that the lvaluedness of substr()'s return value, as long as the
    > >fact that you can EVEN take references of it and modify the string
    > >with a sort of action-at-distance was put there specifically for
    > >performance issues. At some point there were problems with
    > >substitutions having a lenght larger than the substituted IalsoIRC,
    > >but they should be solved in recent enough perls.
    > >
    > >See: <http://perlmonks.org/?node_id=498434>
    > >
    > >
    > >Michele

    >
    > 5.8.6 has problems:


    I think it is your expectations that have problems. But you haven't
    described what your expectations are, so it is hard to tell.

    The lvals remember the offset and length. If the main string gets
    rearranged, the lval doesn't try to change the offset and length in an
    attempt to trace that rearrangement. Can you imagine the morass if they
    did? Instead, it keeps the "window" the same and lets characters move
    around beneath it.

    Also, if you assign to the lval with a string of a different length,
    the lval still remembers it's length to be the originally created one, not
    the length of the string just assigned to it. So you can assign and
    then immediately read and get a different thing than what you just
    assigned. But I don't know that the alternative would be any less odd.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Nov 11, 2008
    #19
  20. [A complimentary Cc of this posting was sent to

    <>], who wrote in article <20081111165556.884$>:
    > > > >> Simple experiments show that it is still buggy with 5.8.8: code
    > > > >> below returns

    > >
    > > > >> change_nth 7, 'lazy', map{ substr $bigScalar, $_->[0], $_->[1] }
    > > > ^
    > > > \

    > > Nope.

    >
    > It will work provided you make the obvious change to change_nth to do the
    > dereference.


    No. It would not work this way, and it would not demonstrate the bug either...

    [There are many ways to work-around the bug, of course. For
    example, use C instead of Perl... ;-/]

    Yours,
    Ilya
    Ilya Zakharevich, Nov 12, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kees Hoogendijk

    getline and substr

    Kees Hoogendijk, Dec 20, 2003, in forum: C++
    Replies:
    4
    Views:
    539
    Kees Hoogendijk
    Dec 21, 2003
  2. entropy123

    [C++] Odd Problem with "substr"

    entropy123, Jun 1, 2005, in forum: C++
    Replies:
    7
    Views:
    534
    Stephen Howe
    Jun 2, 2005
  3. Kavya
    Replies:
    9
    Views:
    491
    Dik T. Winter
    Oct 28, 2006
  4. Replies:
    11
    Views:
    677
    James Kuyper
    Sep 22, 2008
  5. Julian Mehnle
    Replies:
    0
    Views:
    223
    Julian Mehnle
    Jul 17, 2003
Loading...

Share This Page