Merge pull request #6 from jimeh/performance-improvements

feat(performance): improve core undenting performance by 20-30x
This commit is contained in:
2021-02-22 22:47:02 +00:00
committed by GitHub
2 changed files with 342 additions and 32 deletions

105
undent.go
View File

@@ -5,15 +5,85 @@ package undent
import (
"fmt"
"io"
"regexp"
)
var matcher = regexp.MustCompile(`(?m)^([ \t]*)(?:\S)`)
const (
tab = 9
lf = 10
spc = 32
)
// Bytes removes leading indentation/white-space from given string and returns
// it as a byte slice.
func Bytes(s string) []byte {
return []byte(String(s))
if len(s) == 0 {
return []byte{}
}
// find line feeds
lfs := []int{}
if s[0] != lf {
lfs = append(lfs, -1)
}
for i := 0; i < len(s); i++ {
if s[i] == lf {
lfs = append(lfs, i)
}
}
// find smallest indent relative to each line-feed
min := 99999999999
count := 0
for i := 0; i < len(lfs); i++ {
offset := lfs[i]
end := len(s) - 1
if i+1 < len(lfs) {
end = lfs[i+1]
}
if offset+1 >= end {
continue
}
indent := 0
lineSeek:
for n := offset + 1; n < end && indent < min; n++ {
switch s[n] {
case spc, tab:
indent++
default:
break lineSeek
}
}
if indent < min {
min = indent
}
if indent > 0 {
count++
}
}
// extract each line without indentation
out := make([]byte, 0, len(s)-(min*count))
for i := 0; i < len(lfs); i++ {
offset := lfs[i] + 1
end := len(s)
if i+1 < len(lfs) {
end = lfs[i+1] + 1
}
if offset+min < end {
out = append(out, s[offset+min:end]...)
} else if offset < end {
out = append(out, s[offset:end]...)
}
}
return out
}
// Bytesf removes leading indentation/white-space from given format string
@@ -25,34 +95,7 @@ func Bytesf(format string, a ...interface{}) []byte {
// String removes leading indentation/white-space from given string.
func String(s string) string {
if len(s) > 0 && s[0] == '\n' {
s = s[1:]
}
matches := matcher.FindAllString(s, -1)
if len(matches) == 0 {
return s
}
index := 0
length := len(matches[0])
for i, s := range matches[1:] {
l := len(s)
if l < length {
index = i + 1
length = l
}
}
if length <= 1 {
return s
}
indent := matches[index][0 : length-1]
return regexp.MustCompile(
`(?m)^`+regexp.QuoteMeta(indent),
).ReplaceAllLiteralString(s, "")
return string(Bytes(s))
}
// Stringf removes leading indentation/white-space from given format string

View File

@@ -59,6 +59,21 @@ var stringTestCases = []struct {
"foo": [
"bar"
]
}`,
},
{
name: "multi-line space indented without any leading line-breaks",
s: ` {
"hello": "world",
"foo": [
"bar"
]
}`,
want: `{
"hello": "world",
"foo": [
"bar"
]
}`,
},
{
@@ -98,7 +113,22 @@ var stringTestCases = []struct {
}`,
},
{
name: "multi-line tab indented with leading line breaks",
name: "multi-line tab indented without any leading line-breaks",
s: ` {
"hello": "world",
"foo": [
"bar"
]
}`,
want: `{
"hello": "world",
"foo": [
"bar"
]
}`,
},
{
name: "multi-line tab indented with leading line-breaks",
s: `
@@ -197,6 +227,108 @@ world
foo
bar`,
},
{
name: "long block of text",
s: `
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc
ornare, tellus vel luctus tristique, ipsum ante varius mauris, non
hendrerit tellus urna quis ex. Donec efficitur arcu sed iaculis
lobortis. Phasellus facilisis vitae mi quis accumsan. Suspendisse
rhoncus viverra odio ultricies rhoncus. Cras laoreet tortor
vestibulum pharetra luctus. Vivamus sit amet volutpat elit.
Suspendisse feugiat lectus id arcu sollicitudin tincidunt. Duis ut
sem auctor orci sodales varius in ac odio. Nullam finibus odio at
lacus tristique malesuada.
Morbi nisl nulla, euismod eu enim in, tincidunt varius turpis. Morbi
ullamcorper tortor mi, ut aliquam metus posuere vel. Etiam vel dui
at quam placerat sollicitudin. Proin aliquam justo vitae mauris
gravida porta. Praesent hendrerit egestas ligula, faucibus tincidunt
tortor aliquet at. Ut luctus vehicula arcu eget cursus. Suspendisse
eget enim mollis, condimentum lacus eu, viverra nulla. Aenean vel
sapien eget enim convallis accumsan. Donec dictum ullamcorper leo
placerat sollicitudin. Pellentesque habitant morbi tristique
senectus et netus et malesuada fames ac turpis egestas. Vestibulum
volutpat mattis est, a feugiat purus feugiat at. Quisque at velit ut
mauris convallis sodales a et erat. Mauris condimentum augue sit
amet arcu sodales, aliquet ultrices ipsum tempor. Donec scelerisque
mi ligula, vel volutpat velit posuere a. Sed faucibus dui pulvinar
lorem commodo egestas. In facilisis suscipit lacus non suscipit.
Nunc dictum est nulla, a rhoncus mi posuere id. Morbi at tempus
augue. Quisque ac nibh auctor velit auctor placerat id non eros.
Nulla condimentum quam id risus suscipit, ut fermentum mauris
lacinia. Vestibulum suscipit rutrum ex, sed vulputate nisi tempus
ultricies. Sed id ante pretium, accumsan sapien eget, malesuada
quam. Phasellus quis commodo enim. Vivamus in purus ac lorem ornare
posuere non eu quam. Sed arcu tortor, gravida quis fringilla nec,
ultricies et sem. Pellentesque arcu enim, tempor id nisl at, rhoncus
efficitur sem. Ut quis placerat quam. Donec maximus a risus sed
posuere. Curabitur pretium a diam non aliquet.
Class aptent taciti sociosqu ad litora torquent per conubia nostra,
per inceptos himenaeos. Morbi volutpat felis leo, vel ultrices orci
bibendum ac. Integer eu mattis urna. Donec dictum vehicula
fermentum. Pellentesque a rutrum ipsum. Donec ultricies elit purus,
eget viverra tellus tristique sed. In hac habitasse platea dictumst.
Duis elementum semper elit, sit amet rhoncus lacus dictum ac. Nunc
pretium enim ac urna efficitur, eget facilisis enim interdum.
Vivamus vel lectus lacus. Praesent vestibulum vel ligula eget
cursus. Quisque eu dignissim erat. Quisque maximus arcu eu turpis
pulvinar egestas. Nam aliquet neque sed tellus finibus mollis.
Phasellus consequat nibh nec ornare egestas. Donec at pellentesque
lorem.`,
want: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc
ornare, tellus vel luctus tristique, ipsum ante varius mauris, non
hendrerit tellus urna quis ex. Donec efficitur arcu sed iaculis
lobortis. Phasellus facilisis vitae mi quis accumsan. Suspendisse
rhoncus viverra odio ultricies rhoncus. Cras laoreet tortor
vestibulum pharetra luctus. Vivamus sit amet volutpat elit.
Suspendisse feugiat lectus id arcu sollicitudin tincidunt. Duis ut
sem auctor orci sodales varius in ac odio. Nullam finibus odio at
lacus tristique malesuada.
Morbi nisl nulla, euismod eu enim in, tincidunt varius turpis. Morbi
ullamcorper tortor mi, ut aliquam metus posuere vel. Etiam vel dui
at quam placerat sollicitudin. Proin aliquam justo vitae mauris
gravida porta. Praesent hendrerit egestas ligula, faucibus tincidunt
tortor aliquet at. Ut luctus vehicula arcu eget cursus. Suspendisse
eget enim mollis, condimentum lacus eu, viverra nulla. Aenean vel
sapien eget enim convallis accumsan. Donec dictum ullamcorper leo
placerat sollicitudin. Pellentesque habitant morbi tristique
senectus et netus et malesuada fames ac turpis egestas. Vestibulum
volutpat mattis est, a feugiat purus feugiat at. Quisque at velit ut
mauris convallis sodales a et erat. Mauris condimentum augue sit
amet arcu sodales, aliquet ultrices ipsum tempor. Donec scelerisque
mi ligula, vel volutpat velit posuere a. Sed faucibus dui pulvinar
lorem commodo egestas. In facilisis suscipit lacus non suscipit.
Nunc dictum est nulla, a rhoncus mi posuere id. Morbi at tempus
augue. Quisque ac nibh auctor velit auctor placerat id non eros.
Nulla condimentum quam id risus suscipit, ut fermentum mauris
lacinia. Vestibulum suscipit rutrum ex, sed vulputate nisi tempus
ultricies. Sed id ante pretium, accumsan sapien eget, malesuada
quam. Phasellus quis commodo enim. Vivamus in purus ac lorem ornare
posuere non eu quam. Sed arcu tortor, gravida quis fringilla nec,
ultricies et sem. Pellentesque arcu enim, tempor id nisl at, rhoncus
efficitur sem. Ut quis placerat quam. Donec maximus a risus sed
posuere. Curabitur pretium a diam non aliquet.
Class aptent taciti sociosqu ad litora torquent per conubia nostra,
per inceptos himenaeos. Morbi volutpat felis leo, vel ultrices orci
bibendum ac. Integer eu mattis urna. Donec dictum vehicula
fermentum. Pellentesque a rutrum ipsum. Donec ultricies elit purus,
eget viverra tellus tristique sed. In hac habitasse platea dictumst.
Duis elementum semper elit, sit amet rhoncus lacus dictum ac. Nunc
pretium enim ac urna efficitur, eget facilisis enim interdum.
Vivamus vel lectus lacus. Praesent vestibulum vel ligula eget
cursus. Quisque eu dignissim erat. Quisque maximus arcu eu turpis
pulvinar egestas. Nam aliquet neque sed tellus finibus mollis.
Phasellus consequat nibh nec ornare egestas. Donec at pellentesque
lorem.`,
},
}
var stringfTestCases = []struct {
@@ -254,6 +386,22 @@ var stringfTestCases = []struct {
"foo": [
42
]
}`,
},
{
name: "multi-line space indented without any leading line-breaks",
s: ` {
"hello": "%s",
"foo": [
%d
]
}`,
a: []interface{}{"world", 42},
want: `{
"hello": "world",
"foo": [
42
]
}`,
},
{
@@ -292,6 +440,22 @@ var stringfTestCases = []struct {
"foo": [
42
]
}`,
},
{
name: "multi-line tab indented without any leading line-breaks",
s: ` {
"hello": "%s",
"foo": [
%d
]
}`,
a: []interface{}{"world", 42},
want: `{
"hello": "world",
"foo": [
42
]
}`,
},
{
@@ -400,6 +564,109 @@ world
foo
42`,
},
{
name: "long block of text",
s: `
Lorem %s dolor sit amet, consectetur adipiscing elit. Nunc
ornare, tellus vel luctus tristique, ipsum ante varius mauris, non
hendrerit tellus urna quis ex. %s efficitur arcu sed iaculis
lobortis. Phasellus facilisis vitae mi quis accumsan. Suspendisse
rhoncus viverra odio ultricies rhoncus. Cras laoreet tortor
vestibulum pharetra luctus. Vivamus sit amet volutpat elit.
Suspendisse feugiat lectus id arcu sollicitudin tincidunt. Duis ut
sem auctor orci sodales varius in ac odio. Nullam finibus odio at
lacus tristique malesuada.
Morbi nisl nulla, euismod eu enim in, tincidunt varius turpis. Morbi
ullamcorper tortor mi, ut aliquam metus posuere vel. Etiam vel dui
at quam placerat sollicitudin. Proin aliquam justo vitae mauris
gravida porta. Praesent hendrerit egestas ligula, faucibus tincidunt
tortor aliquet at. Ut luctus vehicula arcu eget cursus. Suspendisse
eget enim mollis, condimentum lacus eu, viverra nulla. Aenean vel
sapien eget enim convallis accumsan. Donec dictum ullamcorper leo
placerat sollicitudin. Pellentesque habitant morbi tristique
senectus et netus et malesuada fames ac turpis egestas. Vestibulum
volutpat mattis est, a feugiat purus feugiat at. Quisque at velit ut
mauris convallis sodales a et erat. Mauris condimentum augue sit
amet arcu sodales, aliquet ultrices ipsum tempor. Donec scelerisque
mi ligula, vel volutpat velit posuere a. Sed faucibus dui pulvinar
lorem commodo egestas. In facilisis suscipit lacus non suscipit.
Nunc dictum est nulla, a rhoncus mi posuere id. Morbi at tempus
augue. Quisque ac nibh auctor velit auctor placerat id non eros.
Nulla condimentum quam id risus suscipit, ut fermentum mauris
lacinia. Vestibulum suscipit rutrum ex, sed vulputate nisi tempus
ultricies. Sed id ante pretium, accumsan sapien eget, malesuada
quam. Phasellus quis commodo enim. Vivamus in purus ac lorem ornare
posuere non eu quam. Sed arcu tortor, gravida quis fringilla nec,
ultricies et sem. Pellentesque arcu enim, tempor id nisl at, rhoncus
efficitur sem. Ut quis placerat quam. Donec maximus a risus sed
posuere. Curabitur pretium a diam non aliquet.
Class aptent taciti sociosqu ad litora torquent per conubia nostra,
per inceptos himenaeos. Morbi volutpat felis leo, vel ultrices orci
bibendum ac. Integer eu mattis urna. Donec dictum vehicula
fermentum. Pellentesque a rutrum ipsum. Donec ultricies elit purus,
eget viverra tellus tristique sed. In hac habitasse platea dictumst.
Duis elementum semper elit, sit amet rhoncus lacus dictum ac. Nunc
pretium enim ac urna efficitur, eget facilisis enim interdum.
Vivamus vel lectus lacus. Praesent vestibulum vel ligula eget
cursus. Quisque eu dignissim erat. Quisque maximus arcu eu turpis
pulvinar egestas. Nam aliquet neque sed tellus finibus mollis.
Phasellus consequat nibh nec ornare egestas. Donec at pellentesque
lorem.`,
a: []interface{}{"ipsum", "Donec"},
want: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc
ornare, tellus vel luctus tristique, ipsum ante varius mauris, non
hendrerit tellus urna quis ex. Donec efficitur arcu sed iaculis
lobortis. Phasellus facilisis vitae mi quis accumsan. Suspendisse
rhoncus viverra odio ultricies rhoncus. Cras laoreet tortor
vestibulum pharetra luctus. Vivamus sit amet volutpat elit.
Suspendisse feugiat lectus id arcu sollicitudin tincidunt. Duis ut
sem auctor orci sodales varius in ac odio. Nullam finibus odio at
lacus tristique malesuada.
Morbi nisl nulla, euismod eu enim in, tincidunt varius turpis. Morbi
ullamcorper tortor mi, ut aliquam metus posuere vel. Etiam vel dui
at quam placerat sollicitudin. Proin aliquam justo vitae mauris
gravida porta. Praesent hendrerit egestas ligula, faucibus tincidunt
tortor aliquet at. Ut luctus vehicula arcu eget cursus. Suspendisse
eget enim mollis, condimentum lacus eu, viverra nulla. Aenean vel
sapien eget enim convallis accumsan. Donec dictum ullamcorper leo
placerat sollicitudin. Pellentesque habitant morbi tristique
senectus et netus et malesuada fames ac turpis egestas. Vestibulum
volutpat mattis est, a feugiat purus feugiat at. Quisque at velit ut
mauris convallis sodales a et erat. Mauris condimentum augue sit
amet arcu sodales, aliquet ultrices ipsum tempor. Donec scelerisque
mi ligula, vel volutpat velit posuere a. Sed faucibus dui pulvinar
lorem commodo egestas. In facilisis suscipit lacus non suscipit.
Nunc dictum est nulla, a rhoncus mi posuere id. Morbi at tempus
augue. Quisque ac nibh auctor velit auctor placerat id non eros.
Nulla condimentum quam id risus suscipit, ut fermentum mauris
lacinia. Vestibulum suscipit rutrum ex, sed vulputate nisi tempus
ultricies. Sed id ante pretium, accumsan sapien eget, malesuada
quam. Phasellus quis commodo enim. Vivamus in purus ac lorem ornare
posuere non eu quam. Sed arcu tortor, gravida quis fringilla nec,
ultricies et sem. Pellentesque arcu enim, tempor id nisl at, rhoncus
efficitur sem. Ut quis placerat quam. Donec maximus a risus sed
posuere. Curabitur pretium a diam non aliquet.
Class aptent taciti sociosqu ad litora torquent per conubia nostra,
per inceptos himenaeos. Morbi volutpat felis leo, vel ultrices orci
bibendum ac. Integer eu mattis urna. Donec dictum vehicula
fermentum. Pellentesque a rutrum ipsum. Donec ultricies elit purus,
eget viverra tellus tristique sed. In hac habitasse platea dictumst.
Duis elementum semper elit, sit amet rhoncus lacus dictum ac. Nunc
pretium enim ac urna efficitur, eget facilisis enim interdum.
Vivamus vel lectus lacus. Praesent vestibulum vel ligula eget
cursus. Quisque eu dignissim erat. Quisque maximus arcu eu turpis
pulvinar egestas. Nam aliquet neque sed tellus finibus mollis.
Phasellus consequat nibh nec ornare egestas. Donec at pellentesque
lorem.`,
},
}
func TestBytes(t *testing.T) {