Perl push line optimization in csv using split

I would like to optimize this Perl:

push_csv($string,$addthis,$position);

to place the lines inside the CSV line.

eg. if $string="one,two,,four"; $addthis="three"; $position=2;
it push_csv($string,$addthis,$position)changes the value$string = "one,two,three,four";

sub push_csv {

    my @fields = split /,/, $_[0]; # split original string by commas;
    $_[1] =~ s/,//g;               # remove commas in $addthis
    $fields[$_[2]] = $_[1];        # put the $addthis string into
                                   # the array position $position.
    $_[0] = join ",", @fields;     # join the array with commas back
                                   # into the string.
}

This is a bottleneck in my code, as it needs to be called several million times.

If you own Perl, can you take a look at it and suggest optimizations / alternatives? Thanks in advance!:)


EDIT: Converting to @fields and back to a string takes a lot of time, I just thought about how to speed it up, where I have more than one subtitle per line. Separate once, then click multiple elements into an array, then attach once to the end.

+5
source share
5 answers

Text::CSV CSV. , XS, , , , Perl. , , , , .

use Text::CSV;
my $csv = Text::CSV->new;

my $line = 'foo,,fubb';
$csv->parse($line);

my @fields = $csv->fields;
$fields[1] = 'bar';

$csv->combine(@fields); 
print $csv->string;      # foo,bar,fubb
+3

, - ?

, Data:: Locations.

(untested, unbenchmarked, , , ...)

sub push_csv {
    $_[1] =~ y/,//d;
    $_[0] =~ s/^(?:[^,]*,){$_[2]}\K[^,]*/$_[1]/;
    return;
}
+2

:

  • tr/,//d s/,//g, . , ysth suggestion y/,//d
  • split , . $position = 1, 10 , , . split . , . , , , .
  • , . , .

Text::CSV, , sub Perl ( ):

sub push_csv {

    my ( $items, $positions ) = @_[1..2];

    # Test inputs
    warn "No. of items to add & positions not equal"
      and
        return unless @{$items} == @{$positions};

    my $maxPos;  # Find the maximum position number

    for my $position ( @{$positions} ) {

        $maxPos ||= $position;
        $maxPos = $position if $maxPos < $position;
    }

    my @fields = split /,/ , $_[0], $maxPos+2;  # Split only as much as needed

    splice ( @fields, $positions->[$_], 1, $items->[$_] ) for 0 .. $#{$items};
    $_[0] = join ',' , @fields;
    print $_[0],"\n";
}

use strict;
use warnings;

my $csvString = 'one,two,,four,,six';
my @missing = ( 'three', 'five' );
my @positions = ( 2, 4 );

push_csv ( $csvString, \@missing, \@positions );
print $csvString;   # Prints 'one,two,three,four,five,six'
+1

split ting join ... split join . split , , (, , ) , join, , " .

:.

#!/usr/bin/env perl

use strict;
use warnings;

# Start with some CSV-ish data
my $initial_data = 'foo,bar,baz';

# Split it into an arrayref
my $data = [ split /,/, $initial_data ];

for (1 .. 1_000_000) {
  # Pointless call to push_csv, just to make it run
  push_csv($data, $_, $_ % 3);
}

# Turn it back into a string and display it
my $final_data = join ',', @$data;
print "Result: $final_data\n";

sub push_csv {
  my ($data_ref, $value, $position) = @_;
  $$data_ref[$position] = $value;
  # Alternately:
  # $data_ref->[$position] = $value;
}

, , push_csv , , inline , - , push_csv 70% ( 0,515 0,167).

+1

, splice, join ?

, s/// - , .

0

All Articles