I was looking at text/template/parse/lex.go and noticed it seemed to be very inefficient in how it searched for {{ in its input. I rewrote lexText to us strings.Index rather than calling l.next() for every single rune in the string. The results were up to a 9x speed improvement, depending on the density of {{'s in the text.
My results were: BenchmarkOldR512-4 100000 12300 ns/op BenchmarkNewR512-4 300000 4513 ns/op BenchmarkOldT512-4 100000 23600 ns/op BenchmarkNewT512-4 100000 13898 ns/op BenchmarkOldR8k-4 10000 133261 ns/op BenchmarkNewR8k-4 100000 14852 ns/op BenchmarkOldT8k-4 5000 264654 ns/op BenchmarkNewT8k-4 10000 135056 ns/op BenchmarkOldMany-4 300 5577909 ns/op BenchmarkNewMany-4 300 5632914 ns/op BenchmarkOldR512-4 100000 12100 ns/op BenchmarkNewR512-4 300000 4507 ns/op BenchmarkOldT512-4 100000 23297 ns/op BenchmarkNewT512-4 100000 14699 ns/op BenchmarkOldR8k-4 10000 136474 ns/op BenchmarkNewR8k-4 100000 16566 ns/op BenchmarkOldT8k-4 5000 266256 ns/op BenchmarkNewT8k-4 10000 137201 ns/op BenchmarkOldMany-4 300 5606573 ns/op BenchmarkNewMany-4 300 5596660 ns/op BenchmarkOldR512-4 100000 12150 ns/op BenchmarkNewR512-4 300000 4405 ns/op BenchmarkOldT512-4 100000 21539 ns/op BenchmarkNewT512-4 100000 13735 ns/op BenchmarkOldR8k-4 10000 133586 ns/op BenchmarkNewR8k-4 100000 14076 ns/op BenchmarkOldT8k-4 5000 264374 ns/op BenchmarkNewT8k-4 10000 132618 ns/op BenchmarkOldMany-4 300 5622040 ns/op BenchmarkNewMany-4 300 5638461 ns/op R512 was 512 bytes of Lorem Ipsum text with no {{}}'s R8K was 8,192 bytes of Lorem Ipsum text with no {{}}'s The T versions are the same, but with all occurrences of ipsum changed to {{.}} (3 times in T512 and 13 times in T8K). The Many version was the string "{{.}}" repeated 1000 times. The old code: for { delim, trimSpace := l.atLeftDelim() if delim { trimLength := Pos(0) if trimSpace { trimLength = rightTrimLength(l.input[l.start:l.pos]) } l.pos -= trimLength if l.pos > l.start { l.emit(itemText) } l.pos += trimLength l.ignore() return lexLeftDelim } if l.next() == eof { break } } The new code: l.width = 0 if x := strings.Index(l.input[l.pos:], l.leftDelim); x >= 0 { ldn := Pos(len(l.leftDelim)) l.pos += Pos(x) trimLength := Pos(0) if strings.HasPrefix(l.input[l.pos+ldn:], leftTrimMarker) { trimLength = rightTrimLength(l.input[l.start:l.pos]) } l.pos -= trimLength if l.pos > l.start { l.emit(itemText) } l.pos += trimLength l.ignore() return lexLeftDelim } else { l.pos = Pos(len(l.input)) } Is this something that would be accepted into the standard library? Thanks, -Paul -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.