How expensive is it to dereference a ref array in Perl?

I am curious if Perl internal objects create a copy of ref values โ€‹โ€‹to create an array? For example, the following displays the last and first value of a delimited string:

say @{[ split( q{\|}, q{bar|is|foo} ) ]}[-1,0]; # STDOUT: foobar\n 
  • Does the operation first create a list through split and create a ref array, and then copy the values โ€‹โ€‹of the ref array to the new array when dereferencing?
  • Does it expand the current array in place?

Since dereferencing is so common, I'm sure it is optimized, I'm just curious how expensive it is compared to creating an array from a list initially, for example:

 my @parts = split q{\|}, q{bar|is|foo}; say @parts[-1,0]; 

Purpose: to get an idea of โ€‹โ€‹the basic operations without deep penetration into the code

+6
source share
2 answers

vol7ron> How expensive is it to dereference a ref array in Perl?

ikegami> You do more than just dereference an array.

vol7ron> But the question is still standing

Again, this is a useless question. An alternative is never between just dereferencing an array and something else.

But since you insist, for me it is 37 ns (37 billion per second).

 use Benchmark qw( cmpthese ); my %tests = ( deref => 'my @y = @$x;', none => 'my @y = @x;', ); $_ = 'use strict; use warnings; our $x; our @x; ' . $_ for values %tests; { local our @x = (); local our $x = \@x; cmpthese(-3, \%tests); } 

Result:

  Rate deref none deref 3187659/s -- -12% none 3616848/s 13% -- 

The time taken by each size = 1/3187659 s - 1/3616848 s = 37 ns

This is tiny! When dereferencing an array, only 12% of the time spent dereferencing an empty array and copying it to another is taken into account!

Does the operation first create a list through split (1) and create a ref (2) array, and then copy the values โ€‹โ€‹of the ref array to a new array when dereferencing (3)?

  • Yes, split returns a list. Except for scalar context.

  • [ ... ] not only creates a link, but also creates an array and copies the values โ€‹โ€‹into it.

  • No, dereferencing does not copy values.

Does it deploy an existing arrayref in place?

It would be very bad if the link turned into something else. What do you really mean?

+1
source

Here is a benchmark

 #!/usr/bin/perl use strict; use warnings; use 5.010; use Benchmark qw(:all); my @list = ('foo')x1_000_000; my $str = join('|',@list); my $count = -2; cmpthese($count, { 'deref' => sub { my $parts = [ split( q{\|}, $str ) ]; my @res = @$parts[-1,0]; }, 'array' => sub { my @parts = split q{\|}, $str; my @res = @parts[-1,0]; }, }); 

I just change say to assignment.
Windows 7, perl 5.14.2

  Rate deref array deref 2.02/s -- -38% array 3.23/s 60% -- 

Depending on the environment, I get Linux 64 bit, perl 5.14.2

  Rate deref array deref 3.00/s -- -35% array 4.65/s 55% -- 

and Linux 32 bit, perl 5.8.4

  Rate array deref array 1.96/s -- -35% deref 3.00/s 53% -- 
+3
source

Source: https://habr.com/ru/post/954514/


All Articles