diff --git a/utf8/reverse/README.md b/utf8/reverse/README.md index 154028c..da05732 100644 --- a/utf8/reverse/README.md +++ b/utf8/reverse/README.md @@ -5,9 +5,24 @@ Функция принимает на вход юникодную строку и должна возвращать строку, состоящую из тех же юникодных рун, но записанных в обратном порядке. +Если строка содержит последовательность байт, не образующую корректный utf8, нужно развернуть +эту последовательность как отдельные байты. + Обратите внимание в тестах, что некоторые графемы распадаются при обращении строки. Данный эффект связан с тем, что в юникоде некоторые руны умеют комбинироваться в одну графему. +Ваша реализация должна быть достаточно эффективна. На нашем бенчмарке в тестовой системе +она должна работать не хуже авторского решения. В частности, код должен делать не больше двух +аллокаций. Эту функцию можно написать с одной аллокацией, но придётся использовать пакет unsafe. +Работу с unsafe мы будем разбирать дальше в курсе. + +``` +goos: linux +goarch: amd64 +pkg: gitlab.com/slon/shad-go/utf8/reverse +BenchmarkReverse-4 395078 2763 ns/op 1792 B/op 2 allocs/op +PASS +``` ### Примеры Как запустить все тесты: diff --git a/utf8/reverse/reverse_test.go b/utf8/reverse/reverse_test.go index 8509595..d7901b6 100644 --- a/utf8/reverse/reverse_test.go +++ b/utf8/reverse/reverse_test.go @@ -2,6 +2,7 @@ package reverse import ( "fmt" + "strings" "testing" "github.com/stretchr/testify/require" @@ -36,9 +37,20 @@ func TestReverse(t *testing.T) { {input: "🇩🇪", output: "🇪🇩"}, // NB: Флаг распался. :) {input: "🏳️‍🌈", output: "🌈‍️🏳"}, + {input: "\xff\x00\xff\x00", output: "\x00\xff\x00\xff"}, } { t.Run(fmt.Sprintf("#%v: %v", i, tc.input), func(t *testing.T) { require.Equal(t, tc.output, Reverse(tc.input)) }) } } + +func BenchmarkReverse(b *testing.B) { + input := strings.Repeat("🙂🙂", 100) + + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + _ = Reverse(input) + } +} diff --git a/utf8/spacecollapse/README.md b/utf8/spacecollapse/README.md index d7db129..e61478e 100644 --- a/utf8/spacecollapse/README.md +++ b/utf8/spacecollapse/README.md @@ -5,9 +5,12 @@ Функция принимает на вход юникодную строку и должна возвращать строку, состоящую из тех же символов, но где все подряд идущие группы пробельных символов заменены на ' ' (один обычный пробел). -### Примеры +Некорректную utf8 последовательность функция должна оставлять без изменений. + +## Примеры Как запустить все тесты: + ``` go test -v ./utf8/spacecollapse/... ``` diff --git a/utf8/spacecollapse/collapse_test.go b/utf8/spacecollapse/collapse_test.go index 77d9d80..1d3f208 100644 --- a/utf8/spacecollapse/collapse_test.go +++ b/utf8/spacecollapse/collapse_test.go @@ -2,6 +2,7 @@ package spacecollapse import ( "fmt" + "strings" "testing" "github.com/stretchr/testify/require" @@ -21,9 +22,20 @@ func TestCollapseSpaces(t *testing.T) { {input: "\t*", output: " *"}, {input: " \t \t ", output: " "}, {input: " \tx\t ", output: " x "}, + {input: "\xff\x00\xff\x00", output: "\xff\x00\xff\x00"}, } { t.Run(fmt.Sprintf("#%v: %v", i, tc.input), func(t *testing.T) { require.Equal(t, tc.output, CollapseSpaces(tc.input)) }) } } + +func BenchmarkCollapse(b *testing.B) { + input := strings.Repeat("🙂 🙂", 100) + + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + _ = CollapseSpaces(input) + } +}