I've been reading Advanced Perl Programming lately, and within there is an admonition that one should "almost always" use Perl's arrays instead of a linked list. The rationale is that the built-in functions (pop, push, shift, and unshift) are quite fast -- likely much faster than anything one could implement oneself in pure Perl.
I think it's valuable advice, but the set of functions the author lists deal only with the ends of arrays. One of the values, to me, of the linked list is the ease with which one can insert values in the middle of the list. The only sensible Perl-array idiom I was able to come up with for doing this is to use array slices:
sub insert_array_elem { my ($ra, $elem, $index) = @_; # insert $elem before $ra->[$index] if ($index < 0) { # convert negative indexes to positive equiv. $index = @$ra + $index; } if ($index == 0) { # at the beginning unshift @$ra, $elem; } elsif ($index == @$ra) { # at the end push @$ra, $elem; } else { # insert between -- makes copy: bad for large arrays? @$ra = @$ra[0..$index-1], $elem, @$ra[$index..@$ra-1]; } }
It seems to me that this method makes a copy of the array anytime you insert a value in the middle of the array. For small-ish arrays, that's fine, but for large arrays, wouldn't that be very slow?
Since I have an upcoming interest in inserting values in the middle of a list of values, I am curious if there is any way of inserting values in the middle of an array that's faster (and more RAM-friendly) than making a full copy for each insert. What can I do?
Update: D'oh! I had completely spaced the existence of splice. Thanks to shmem especially for the benchmark (saved me some work), but also to Fletch and Tanktalus who were first to discuss the use of splice for this purpose.
For the record, or for anyone who might search this node later:
In reply to Linked lists as arrays: inserting values by radiantmatrix
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |