title: How make a TSV processing golang program that is as efficient as `cut`?
body: <p>I have the following Go program to process a TSV input. But it is slower than <code>awk</code> and <code>cut</code>. I know <code>cut</code> uses string manipulate tricks to achieve a fast performance.</p>
  
  <p><a href="https://github.com/coreutils/coreutils/blob/master/src/cut.c" rel="nofollow noreferrer">https://github.com/coreutils/coreutils/blob/master/src/cut.c</a></p>
  
  <p>Is it possible to achieve the same performance as <code>cut</code> with Go (or at least better than <code>awk</code>)? What should things be used in Go to achieve a better performance?</p>
  
  <pre><code>$ ./main_.sh | indent.sh 
  time ./main.go 10 &lt; "$infile" &gt; /dev/null
  
  real    0m1.431s
  user    0m0.978s
  sys 0m0.436s
  time cut -f 10 &lt; "$infile" &gt; /dev/null
  
  real    0m0.252s
  user    0m0.225s
  sys 0m0.025s
  time awk -v FS='\t' -v OFS='\t' -e '{ print $10 }' &lt; "$infile" &gt; /dev/null
  
  real    0m1.134s
  user    0m1.108s
  sys 0m0.024s
  
  $ cat.sh main_.sh 
  #!/usr/bin/env bash
  # vim: set noexpandtab tabstop=2:
  
  infile=$(mktemp)
  seq 10000000 | paste -s -d $'\t\t\t\t\t\t\t\t\t\n' &gt; "$infile"
  set -v
  time ./main.go 10 &lt; "$infile" &gt; /dev/null
  time cut -f 10 &lt; "$infile" &gt; /dev/null
  time awk -v FS='\t' -v OFS='\t' -e '{ print $10 }' &lt; "$infile" &gt; /dev/null
  
  $ cat main.go
  #!/usr/bin/env gorun
  // vim: set noexpandtab tabstop=2:
  package main
  
  import (
      "bufio"
      "fmt"
      "os"
      "strings"
      "strconv"
  )
  
  func main() {
      idx, _ := strconv.Atoi(os.Args[1])
      col := idx - 1
  
      scanner := bufio.NewScanner(os.Stdin)
      for scanner.Scan() {
          line := strings.TrimRight(scanner.Text(), "\n")
          fields := strings.Split(line, "\t")
          fmt.Printf("%s\n", fields[col])
      }
  }
  </code></pre>