use Benchmark qw/cmpthese/; use Test::More; use experimental 'signatures'; # for daxim my $string ="test\nI want length of this line\n test"; my $position = 12; # Note this postion can be any position in any line. # currently considering it inside 2nd line if ($ENV{BENCHMARK}) { cmpthese(-$ENV{BENCHMARK}, { cur_strlen => sub { cur_strlen($string, $position) }, rlindex => sub { rlindex($string, $position) }, op => sub { op($string, $position) }, daxim => sub { daxim($string, $position) }, }); } my @tests = ( [ "\nString\n", 2, 6, 'Surrounded' ], [ "String\n", 2, 6, 'No first \n' ], [ "\nString", 2, 6, 'No last \n' ], [ "String", 2, 6, 'No \n' ], [ "", 0, 0, 'Blank' ], ); if ($ENV{TEST}) { for (@tests) { ($string, $position, my $expected, my $desc) = @$_; is cur_strlen($string, $position), $expected, "cur_strlen: $desc"; is rlindex($string, $position), $expected, "rlindex: $desc"; is op($string, $position), $expected, "op: $desc"; is daxim($string, $position), $expected, "daxim: $desc"; } done_testing; } use Inline C => q@ int cur_strlen(char * str, int pos) { int rindex = 0; int lindex = 0; for (rindex = pos; str[rindex] != '\n' && str[rindex]; rindex++); for (lindex = pos; lindex && str[lindex] != '\n'; lindex--); if (lindex == 0 && str[lindex] != '\n') lindex--; return(rindex - lindex - 1); } @; sub rlindex { my ($str, $pos) = @_; my $right = index $str, "\n", $pos; my $left = rindex $str, "\n", $pos; $right = length $str if $right == -1; $right - $left - 1; } sub daxim($s, $p, $n = "\n") { no warnings 'uninitialized'; my ($prev, $next); while ($s =~ /$n/g) { $prev = $next; $next = pos $s; last if $next > $p; } return $next - $prev; } sub tybalt89 { my ($string, $position) = @_; pos($string) = $position; $string =~ /.*\G.*\n?/; my $length_of_line = length $&; } sub op { my ($str, $pos) = @_; die "str is not defined" unless defined $str; die "pos is not defined" unless defined $pos; my @newlines; # for storing \n positions push @newlines, 0; while ($str =~/\n/g) { push @newlines, pos($str); } my $itr = scalar @newlines - 1; while ($newlines[$itr] > $pos) { $itr--; } my $length_of_line = $newlines[$itr + 1] - $newlines[$itr]; }