github.com/KEINOS/go-countline@v1.1.1-0.20221217083629-60710df7606b/README.md (about)

     1  <!-- markdownlint-disable MD001 MD041 MD050 MD033 -->
     2  [![go1.16+](https://img.shields.io/badge/Go-1.16--latest-blue?logo=go)](https://github.com/KEINOS/go-countline/blob/main/.github/workflows/version-tests.yaml "Supported versions")
     3  [![Go Reference](https://pkg.go.dev/badge/github.com/KEINOS/go-countline.svg)](https://pkg.go.dev/github.com/KEINOS/go-countline#section-documentation "Read generated documentation of the app")
     4  
     5  # go-countline
     6  
     7  Go package "[go-countline](https://github.com/KEINOS/go-countline/cl)" does nothing more than **count the number of lines in a file**, but it tries to count as fast as possible.
     8  
     9  > __Note__: Unlike the "`wc -l`" command, this package counts the last line that does not end in line breaks/line feeds (see the example below).
    10  
    11  ## Usage
    12  
    13  ```go
    14  go get "github.com/KEINOS/go-countline"
    15  ```
    16  
    17  ```go
    18  import "github.com/KEINOS/go-countline/cl"
    19  
    20  func ExampleCountLines() {
    21      for _, sample := range []struct {
    22          Input string
    23      }{
    24          {""},            // --> 0
    25          {"Hello"},       // --> 1
    26          {"Hello\n"},     // --> 1
    27          {"\n"},          // --> 1
    28          {"\n\n"},        // --> 2
    29          {"\nHello"},     // --> 2
    30          {"\nHello\n"},   // --> 2
    31          {"\n\nHello"},   // --> 3
    32          {"\n\nHello\n"}, // --> 3
    33      } {
    34          readerFile := strings.NewReader(sample.Input)
    35  
    36          count, err := cl.CountLines(readerFile)
    37          if err != nil {
    38              log.Fatal(err)
    39          }
    40  
    41          fmt.Printf("%#v --> %v\n", sample.Input, count)
    42      }
    43      // Output:
    44      // "" --> 0
    45      // "Hello" --> 1
    46      // "Hello\n" --> 1
    47      // "\n" --> 1
    48      // "\n\n" --> 2
    49      // "\nHello" --> 2
    50      // "\nHello\n" --> 2
    51      // "\n\nHello" --> 3
    52      // "\n\nHello\n" --> 3
    53  }
    54  ```
    55  
    56  ## Benchmark Status
    57  
    58  Benchmark of counting 1 GiB of file size (72,323,529 lines) on MacBook Pro (Retina, 13-inch, Early 2015, 2.7 GHz Intel Core i5, 4 core).
    59  
    60  ```shellsession
    61  $ go test -benchmem -count 10 -run=^$ -bench BenchmarkCountLines ./... > bench.txt && benchstat bench.txt
    62  name          time/op
    63  CountLines-4  0.39ns ±19%
    64  
    65  name          alloc/op
    66  CountLines-4   1.00B ± 0%
    67  
    68  name          allocs/op
    69  CountLines-4    0.00
    70  ```
    71  
    72  ```go
    73  func BenchmarkCountLines(b *testing.B) {
    74      // 1 GiB size file
    75      pathFile := filepath.Join("testdata", "data_Giant.txt")
    76  
    77      expectNumLines := 72323529
    78  
    79      // Open file
    80      fileReader, err := os.Open(pathFile)
    81      if err != nil {
    82          b.Fatal(err)
    83      }
    84  
    85      b.Cleanup(func() {
    86          fileReader.Close()
    87      })
    88  
    89      b.ResetTimer() // Begin benchmark
    90  
    91      // Run function
    92      actualNumLines, err := cl.CountLines(fileReader)
    93      if err != nil {
    94          b.Fatal(err)
    95      }
    96  
    97      b.StopTimer() // End benchmark
    98  
    99      if expectNumLines != actualNumLines {
   100          b.Fatalf(
   101              "test %v failed: expect=%d, actual=%d",
   102              b.Name(), expectNumLines, actualNumLines,
   103          )
   104      }
   105  }
   106  ```
   107  
   108  <details><summary>bench.txt</summary>
   109  
   110  ```shellsession
   111  $ cat bench.txt
   112  goos: darwin
   113  goarch: amd64
   114  pkg: github.com/KEINOS/go-countline/cl
   115  cpu: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
   116  BenchmarkCountLines-4           1000000000               0.4294 ns/op          1 B/op          0 allocs/op
   117  BenchmarkCountLines-4           1000000000               0.4659 ns/op          1 B/op          0 allocs/op
   118  BenchmarkCountLines-4           1000000000               0.3811 ns/op          1 B/op          0 allocs/op
   119  BenchmarkCountLines-4           1000000000               0.3696 ns/op          1 B/op          0 allocs/op
   120  BenchmarkCountLines-4           1000000000               0.3672 ns/op          1 B/op          0 allocs/op
   121  BenchmarkCountLines-4           1000000000               0.3888 ns/op          1 B/op          0 allocs/op
   122  BenchmarkCountLines-4           1000000000               0.4071 ns/op          1 B/op          0 allocs/op
   123  BenchmarkCountLines-4           1000000000               0.3875 ns/op          1 B/op          0 allocs/op
   124  BenchmarkCountLines-4           1000000000               0.3604 ns/op          1 B/op          0 allocs/op
   125  BenchmarkCountLines-4           1000000000               0.3613 ns/op          1 B/op          0 allocs/op
   126  PASS
   127  ok      github.com/KEINOS/go-countline/cl       85.368s
   128  PASS
   129  ok      github.com/KEINOS/go-countline/cl/spec  0.275s
   130  ```
   131  
   132  </details>
   133  
   134  
   135  - [See other alternative implementations](./cl/_alt)
   136  
   137  ## Contributing
   138  
   139  ### Statuses
   140  
   141  [![Go 1.16~latest](https://github.com/KEINOS/go-countline/actions/workflows/version-tests.yaml/badge.svg)](https://github.com/KEINOS/go-countline/actions/workflows/version-tests.yaml)
   142  [![Test on macOS/Win/Linux](https://github.com/KEINOS/go-countline/actions/workflows/platform-test.yaml/badge.svg)](https://github.com/KEINOS/go-countline/actions/workflows/platform-test.yaml)
   143  [![golangci-lint](https://github.com/KEINOS/go-countline/actions/workflows/golangci-lint.yaml/badge.svg)](https://github.com/KEINOS/go-countline/actions/workflows/golangci-lint.yaml)
   144  
   145  [![codecov](https://codecov.io/gh/KEINOS/go-countline/branch/main/graph/badge.svg?token=St2W66wHNQ)](https://codecov.io/gh/KEINOS/go-countline)
   146  [![Go Report Card](https://goreportcard.com/badge/github.com/KEINOS/go-countline)](https://goreportcard.com/report/github.com/KEINOS/go-countline)
   147  [![CodeQL](https://github.com/KEINOS/go-countline/actions/workflows/codeQL-analysis.yaml/badge.svg)](https://github.com/KEINOS/go-countline/actions/workflows/codeQL-analysis.yaml)
   148  
   149  ### Contribute
   150  
   151  **If you have found a faster way** to count the number of lines in a file, feel free to contribute!
   152  
   153  As long as the new function passes the test, it is merged. It then will be replaced to the main fucntion in the next release after the review by the contributors.
   154  
   155  - [Issues](https://github.com/KEINOS/go-countline/issues): [![Issues](https://img.shields.io/github/issues/KEINOS/go-countline)](https://github.com/KEINOS/go-countline/issues)
   156    - Please provide a reproducible code snippet.
   157  - Pull requests: [![Pull Requests](https://img.shields.io/github/issues-pr/KEINOS/go-countline)](https://github.com/KEINOS/go-countline/pulls)
   158    - Branch: `main`
   159    - **Any pull requests for the better is welcome!**