Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to find number of lines in go?

What I'm using right now:

numlines := strings.Count(editor.Text(), "\n")
fmt.Print(strconv.Itoa(numlines))
message.SetText(strconv.Itoa(numlines))

This is run whenever a text box is updated. What the most go-like way to do this?

like image 741
rawsh Avatar asked Nov 11 '17 16:11

rawsh


People also ask

How do you count lines of code in a project?

If you want to get the lines of code of a single file, you can use cloc <filename>. We're using the command to get the lines of codes of a simple Vue file. It also recognized that it is a VueJS component. We can check all of the lines of code in a file or directory by the command cloc --by-file.

How do I count the number of lines in a string C++?

The only way to find the line count is to read the whole file and count the number of line-end characters. The fastest way to do this is probably to read the whole file into a large buffer with one read operation and then go through the buffer counting the '\n' characters.


1 Answers

That is perfectly fine. But don't forget that if the last character is not a newline character, you have to add 1 to the number of occurrences, as that will be the number of lines (the last line may not end with a newline).

What we might think is that since the substring you're counting is only a single character (a single rune), we could create a custom solution counting only the occurrence of this single character (instead of counting substrings). It may look like this:

func countRune(s string, r rune) int {
    count := 0
    for _, c := range s {
        if c == r {
            count++
        }
    }
    return count
}

(A for range on a string value iterates over its runes.)

And testing it (try it on the Go Playground):

fmt.Println(countRune("asdf\nasdf\nasdf\n", '\n')) // Prints 3

In practice this won't be faster counting newline characters, as that is a single byte in UTF-8 encoding, and strings.Count() is already optimized for counting substrings where the length of the substring is 1:

// Count counts the number of non-overlapping instances of substr in s.
// If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
func Count(s, substr string) int {
    if len(substr) == 1 && cpu.X86.HasPOPCNT {
        return countByte(s, byte(substr[0]))
    }
    return countGeneric(s, substr)
}

func countByte(s string, c byte) int // ../runtime/asm_amd64.s

What could improve the performance of this operation (counting lines) is if you would have access to the "internal" byte or rune array of the editor, so you would not have to call its Text() method, which creates and returns a copy of its content.

like image 90
icza Avatar answered Oct 14 '22 06:10

icza