gitlab.com/thomasboni/go-enry@v1.7.3/benchmark_test.go (about)

     1  package enry
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"log"
     8  	"os"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"testing"
    12  
    13  	"gopkg.in/src-d/enry.v1/data"
    14  )
    15  
    16  type sample struct {
    17  	filename string
    18  	content  []byte
    19  }
    20  
    21  var (
    22  	slow              bool
    23  	overcomeLanguage  string
    24  	overcomeLanguages []string
    25  	samples           []*sample
    26  	samplesDir        string
    27  	cloned            bool
    28  )
    29  
    30  func TestMain(m *testing.M) {
    31  	flag.BoolVar(&slow, "slow", false, "run benchmarks per sample for strategies too")
    32  	flag.Parse()
    33  
    34  	if err := cloneLinguist(linguistURL); err != nil {
    35  		log.Fatal(err)
    36  	}
    37  	if cloned {
    38  		defer os.RemoveAll(filepath.Dir(samplesDir))
    39  	}
    40  
    41  	var err error
    42  	samples, err = getSamples(samplesDir)
    43  	if err != nil {
    44  		log.Fatal(err)
    45  	}
    46  
    47  	os.Exit(m.Run())
    48  }
    49  
    50  func cloneLinguist(linguistURL string) error {
    51  	repoLinguist := os.Getenv(linguistClonedEnvVar)
    52  	cloned = repoLinguist == ""
    53  	if cloned {
    54  		var err error
    55  		repoLinguist, err = ioutil.TempDir("", "linguist-")
    56  		if err != nil {
    57  			return err
    58  		}
    59  	}
    60  
    61  	samplesDir = filepath.Join(repoLinguist, "samples")
    62  
    63  	if cloned {
    64  		cmd := exec.Command("git", "clone", linguistURL, repoLinguist)
    65  		if err := cmd.Run(); err != nil {
    66  			return err
    67  		}
    68  	}
    69  
    70  	cwd, err := os.Getwd()
    71  	if err != nil {
    72  		return err
    73  	}
    74  
    75  	if err = os.Chdir(repoLinguist); err != nil {
    76  		return err
    77  	}
    78  
    79  	cmd := exec.Command("git", "checkout", data.LinguistCommit)
    80  	if err := cmd.Run(); err != nil {
    81  		return err
    82  	}
    83  
    84  	if err = os.Chdir(cwd); err != nil {
    85  		return err
    86  	}
    87  
    88  	return nil
    89  }
    90  
    91  func getSamples(dir string) ([]*sample, error) {
    92  	samples := make([]*sample, 0, 2000)
    93  	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
    94  		if err != nil {
    95  			return err
    96  		}
    97  
    98  		if info.IsDir() {
    99  			return nil
   100  		}
   101  
   102  		content, err := ioutil.ReadFile(path)
   103  		if err != nil {
   104  			return err
   105  		}
   106  
   107  		s := &sample{
   108  			filename: path,
   109  			content:  content,
   110  		}
   111  		samples = append(samples, s)
   112  		return nil
   113  	})
   114  	return samples, err
   115  }
   116  
   117  func BenchmarkGetLanguageTotal(b *testing.B) {
   118  	if slow {
   119  		b.SkipNow()
   120  	}
   121  
   122  	var o string
   123  	b.Run("GetLanguage()_TOTAL", func(b *testing.B) {
   124  		for n := 0; n < b.N; n++ {
   125  			for _, sample := range samples {
   126  				o = GetLanguage(sample.filename, sample.content)
   127  			}
   128  		}
   129  
   130  		overcomeLanguage = o
   131  	})
   132  }
   133  
   134  func BenchmarkClassifyTotal(b *testing.B) {
   135  	if slow {
   136  		b.SkipNow()
   137  	}
   138  
   139  	var o []string
   140  	b.Run("Classify()_TOTAL", func(b *testing.B) {
   141  		for n := 0; n < b.N; n++ {
   142  			for _, sample := range samples {
   143  				o = DefaultClassifier.Classify(sample.content, nil)
   144  			}
   145  
   146  			overcomeLanguages = o
   147  		}
   148  	})
   149  }
   150  
   151  func BenchmarkStrategiesTotal(b *testing.B) {
   152  	if slow {
   153  		b.SkipNow()
   154  	}
   155  
   156  	benchmarks := benchmarkForAllStrategies("TOTAL")
   157  
   158  	var o []string
   159  	for _, benchmark := range benchmarks {
   160  		b.Run(benchmark.name, func(b *testing.B) {
   161  			for n := 0; n < b.N; n++ {
   162  				for _, sample := range samples {
   163  					o = benchmark.strategy(sample.filename, sample.content, benchmark.candidates)
   164  				}
   165  
   166  				overcomeLanguages = o
   167  			}
   168  		})
   169  	}
   170  }
   171  
   172  func BenchmarkGetLanguagePerSample(b *testing.B) {
   173  	if !slow {
   174  		b.SkipNow()
   175  	}
   176  
   177  	var o string
   178  	for _, sample := range samples {
   179  		b.Run("GetLanguage()_SAMPLE_"+sample.filename, func(b *testing.B) {
   180  			for n := 0; n < b.N; n++ {
   181  				o = GetLanguage(sample.filename, sample.content)
   182  			}
   183  
   184  			overcomeLanguage = o
   185  		})
   186  	}
   187  }
   188  
   189  func BenchmarkClassifyPerSample(b *testing.B) {
   190  	if !slow {
   191  		b.SkipNow()
   192  	}
   193  
   194  	var o []string
   195  	for _, sample := range samples {
   196  		b.Run("Classify()_SAMPLE_"+sample.filename, func(b *testing.B) {
   197  			for n := 0; n < b.N; n++ {
   198  				o = DefaultClassifier.Classify(sample.content, nil)
   199  			}
   200  
   201  			overcomeLanguages = o
   202  		})
   203  	}
   204  }
   205  
   206  func BenchmarkStrategiesPerSample(b *testing.B) {
   207  	if !slow {
   208  		b.SkipNow()
   209  	}
   210  
   211  	benchmarks := benchmarkForAllStrategies("SAMPLE")
   212  
   213  	var o []string
   214  	for _, benchmark := range benchmarks {
   215  		for _, sample := range samples {
   216  			b.Run(benchmark.name+sample.filename, func(b *testing.B) {
   217  				for n := 0; n < b.N; n++ {
   218  					o = benchmark.strategy(sample.filename, sample.content, benchmark.candidates)
   219  				}
   220  
   221  				overcomeLanguages = o
   222  			})
   223  		}
   224  	}
   225  }
   226  
   227  type strategyName struct {
   228  	name       string
   229  	strategy   Strategy
   230  	candidates []string
   231  }
   232  
   233  func benchmarkForAllStrategies(class string) []strategyName {
   234  	return []strategyName{
   235  		{name: fmt.Sprintf("GetLanguagesByModeline()_%s_", class), strategy: GetLanguagesByModeline},
   236  		{name: fmt.Sprintf("GetLanguagesByFilename()_%s_", class), strategy: GetLanguagesByFilename},
   237  		{name: fmt.Sprintf("GetLanguagesByShebang()_%s_", class), strategy: GetLanguagesByShebang},
   238  		{name: fmt.Sprintf("GetLanguagesByExtension()_%s_", class), strategy: GetLanguagesByExtension},
   239  		{name: fmt.Sprintf("GetLanguagesByContent()_%s_", class), strategy: GetLanguagesByContent},
   240  	}
   241  }