... use Inline 'C' => <<'END_C'; #include #include SV * c_walk1(SV *sv) { STRLEN len; const char *s = SvPV_const(sv, len); const char *m = s, *strend = s + len; AV *ret = newAV(); while (s < strend) { if (*s++ == '\n') { av_push(ret, newSVpvn(m, s - m)); m = s; } } return newRV_noinc((SV *) ret); } void c_walk2(SV *sv) { STRLEN len; const char *s = SvPV_const(sv, len); const char *m = s, *strend = s + len; Inline_Stack_Vars; Inline_Stack_Reset; while (s < strend) { if (*s++ == '\n') { Inline_Stack_Push(sv_2mortal(newSVpvn(m, s - m))); m = s; } } Inline_Stack_Done; } END_C # walk1 - receive array ref { my $string = $huge_string; my $start = time; my $lines = c_walk1($string); printf "duration walk1: %0.3f seconds\n", time - $start; printf "%d lines\n\n", scalar(@$lines); } # walk2 - receive list { my $string = $huge_string; my $start = time; my @lines = c_walk2($string); printf "duration walk2: %0.3f seconds\n", time - $start; printf "%d lines\n\n", scalar(@lines); }