さて、index-substr つけましたよ indexsubstr。ダサいけど。

$filedata = "\n$filedata";# 追加!
timethese (10, { # ベンチ
  bin => q{ for my $i (0..0000) { &bin($i); } },
  match => q{ for my $i (0..20000) { &match($i); } },
  hash => q{ for my $i (0..20000) { &hash($i); } },
  index_substr => q{ for my $i (0..20000) { &index_substr($i); } },
} );
(...中略...)
sub index_substr($) {
  my $str = "\n$_[0]\t";
  my $p1 = index($filedata, $str) + length($str);
  my $p2 = index($filedata, "\n", $p1);
  return substr($filedata, $p1, $p2 - $p1);# キーが無かった場合は知ら(ry
}

結果:
Benchmark: timing 10 iterations of bin, hash, index_substr, match...
bin: 28 wallclock secs (27.23 usr + 0.00 sys = 27.23 CPU) @ 0.37/s (n=10)
hash: 0 wallclock secs ( 0.39 usr + 0.00 sys = 0.39 CPU) @ 25.64/s (n=10)
(warning: too few iterations for a reliable count)
index_substr: 289 wallclock secs (286.86 usr + 0.00 sys = 286.86 CPU) @ 0.03/s (n=10)
match: 247 wallclock secs (240.19 usr + 0.02 sys = 240.20 CPU) @ 0.04/s (n=10)
(match は未修正。)