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!**