Когда мы программируем, важно иметь дело со строками. Нам нужно иметь дело со строками при обработке текста в базе данных, отображении веб-текста и хранении текстовых данных. Для строк, поиск, Они обычно используются операций, особенно для объединения, таких как объединение имени человека и возраста вместе для отображения.
В языке Go (golang) существует множество способов объединения строк, так какой из них наиболее эффективен? Поскольку память стоит дорого, а производительность очень важна, иногда случайное преобразование и копирование строк может занять вашу память, а производительность низкая, так что вы должны это учитывать.
один пример
Для любого исследования функции, производительности или метода нет более убедительной шкалы. Здесь мы используем пример для демонстрации объединения различных строк и соответствующего анализа производительности. Этот пример выглядит следующим образом:
昵称:飞雪无情
博客:http://www.flysnow.org/
微信公众号:flysnow_org
В этом примере вышеприведенный контент сращивается с помощью сплайсинга строк.Здесь подчеркивается, что в этом примере перевод строки также является частью сплайсинга строк, потому что мы должны строго сплайсировать вышеприведенный контент.
+ вышивка знака
Этот вид сплайсинга для нас самый простой и легкий в использовании, потому что он не ограничивается языками программирования, например, в языке Go он есть, в Java есть.+
знаковый оператор, вычисляемый во время выполнения. Теперь продемонстрируйте код для этого сплайсинга, хотя он относительно прост.
func StringPlus() string{
var s string
s+="昵称"+":"+"飞雪无情"+"\n"
s+="博客"+":"+"http://www.flysnow.org/"+"\n"
s+="微信公众号"+":"+"flysnow_org"
return s
}
Мы можем сами написать тест варианта использования, который может печатать тот же контент, что и в нашем примере. Итак, какова производительность этого наиболее распространенного метода сращивания строк? Давайте проверим его:
func BenchmarkStringPlus(b *testing.B) {
for i:=0;i<b.N;i++{
StringPlus()
}
}
бегатьgo test -bench=. -benchmem
Просмотрите выходные данные производительности следующим образом:
BenchmarkStringPlus-8 20000000 108 ns/op 144 B/op 2 allocs/op
Каждая операция занимает 108 нс, выполняется 2 выделения памяти и выделяется 114 байт памяти.
сшивка
Это сращивание с помощьюfmt.Sprint
Ряд функций объединяется, а затем возвращает объединенную строку.
func StringFmt() string{
return fmt.Sprint("昵称",":","飞雪无情","\n","博客",":","http://www.flysnow.org/","\n","微信公众号",":","flysnow_org")
}
Для демонстрации код не переносится, что может повлиять на чтение на мобильных телефонах, извините. Мы также тестируем его производительность, чтобы увидеть эффект.
func BenchmarkStringFmt(b *testing.B) {
for i:=0;i<b.N;i++{
StringFmt()
}
}
Запустите, чтобы увидеть результаты теста:
BenchmarkStringFmt-8 5000000 385 ns/op 80 B/op 1 allocs/op
Хотя на операцию приходится только одно выделение памяти, а 80 байт — это немного, каждая операция занимает слишком много времени, а производительность далека от хорошей.+
Работа с номером быстрая.
Присоединяйтесь к сплайсингу
Это используетstrings.Join
Функция выполняет конкатенацию, принимает массив строк и преобразует его в конкатенированную строку.
func StringJoin() string{
s:=[]string{"昵称",":","飞雪无情","\n","博客",":","http://www.flysnow.org/","\n","微信公众号",":","flysnow_org"}
return strings.Join(s,"")
}
func BenchmarkStringJoin(b *testing.B) {
for i:=0;i<b.N;i++{
StringJoin()
}
}
Для удобства код теста производительности собран воедино, а теперь давайте посмотрим на результат теста производительности.
BenchmarkStringJoin-8 10000000 177 ns/op 160 B/op 2 allocs/op
общий и+
Эксплуатация не сильно отличается, примерно в 0,5 раза ниже.
woohoo.fly snow.org/2018/10/28/…
Эффективное соединение строк языка Go (1) | Безжалостный блог Feixue
буферная строчка
Это также используется много, используяbytes.Buffer
Сращивание струн, это очень гибкая структура, можно не только сращивать струны, но иbyte
,rune
и так далее, и понялio.Writer
Интерфейс также очень удобен для написания.
func StringBuffer() string {
var b bytes.Buffer
b.WriteString("昵称")
b.WriteString(":")
b.WriteString("飞雪无情")
b.WriteString("\n")
b.WriteString("博客")
b.WriteString(":")
b.WriteString("http://www.flysnow.org/")
b.WriteString("\n")
b.WriteString("微信公众号")
b.WriteString(":")
b.WriteString("flysnow_org")
return b.String()
}
func BenchmarkStringBuffer(b *testing.B) {
for i:=0;i<b.N;i++{
StringBuffer()
}
}
Посмотрите на его производительность и запустите вывод:
BenchmarkStringBuffer-8 5000000 291 ns/op 336 B/op 3 allocs/op
Вроде не очень, примерно так же, как и самая плохая прошивка fmt, и+
Нет, стыковка соединений далека от хорошей, да и выделений памяти больше. Каждая операция также занимает много времени.
Строительная строчка
Чтобы повысить производительность сплайсинга буферов, начиная с версии go 1.10, был добавлен тип построителя для повышения производительности сплайсинга строк. Его использование почти такое же, как буфера.
func StringBuilder() string {
var b strings.Builder
b.WriteString("昵称")
b.WriteString(":")
b.WriteString("飞雪无情")
b.WriteString("\n")
b.WriteString("博客")
b.WriteString(":")
b.WriteString("http://www.flysnow.org/")
b.WriteString("\n")
b.WriteString("微信公众号")
b.WriteString(":")
b.WriteString("flysnow_org")
return b.String()
}
func BenchmarkStringBuilder(b *testing.B) {
for i:=0;i<b.N;i++{
StringBuilder()
}
}
Официальные лица говорят, что производительность буфера лучше, чем у буфера.Посмотрим на результаты теста производительности.
BenchmarkStringBuilder-8 10000000 170 ns/op 232 B/op 4 allocs/op
Он действительно улучшен, удвоен.Хотя количество выделяемой каждый раз памяти немного больше, размер выделяемой каждый раз памяти меньше размера буфера.
Сравнение производительности
Вышеупомянутый является широко используемым методом сращивания струн. Теперь давайте объединим эти результаты тестов и сравним их. Поскольку эталонный тест показывает только производительность, я установил время теста на 3 с (секунды) и установил время Удлинение удобно для сравнительного анализа. тестирование, и создается файл профиля процессора для анализа производительности.
бегатьgo test -bench=. -benchmem -benchtime=3s -cpuprofile=profile.out
Получены следующие результаты испытаний:
StringPlus-8 50000000 112 ns/op 144 B/op 2 allocs/op
StringFmt-8 20000000 344 ns/op 80 B/op 1 allocs/op
StringJoin-8 30000000 171 ns/op 160 B/op 2 allocs/op
StringBuffer-8 20000000 302 ns/op 336 B/op 3 allocs/op
StringBuilder-8 30000000 171 ns/op 232 B/op 4 allocs/op
мы проходимgo tool pprof profile.out
Взгляните на информацию о профиле процессора, которую мы выводим. Здесь в основном используется команда top.
Showing top 15 nodes out of 89
flat flat% sum% cum cum%
11.99s 42.55% 42.55% 11.99s 42.55% runtime.kevent
6.30s 22.36% 64.90% 6.30s 22.36% runtime.pthread_cond_wait
1.65s 5.86% 70.76% 1.65s 5.86% runtime.pthread_cond_signal
1.11s 3.94% 74.70% 1.11s 3.94% runtime.usleep
1.10s 3.90% 78.60% 1.10s 3.90% runtime.pthread_cond_timedwait_relative_np
0.58s 2.06% 80.66% 0.62s 2.20% runtime.wbBufFlush1
0.51s 1.81% 82.47% 0.51s 1.81% runtime.memmove
0.44s 1.56% 84.03% 1.81s 6.42% fmt.(*pp).printArg
0.39s 1.38% 85.42% 2.36s 8.37% fmt.(*pp).doPrint
0.36s 1.28% 86.69% 0.70s 2.48% fmt.(*buffer).WriteString (inline)
0.34s 1.21% 87.90% 0.93s 3.30% runtime.mallocgc
0.20s 0.71% 88.61% 1.20s 4.26% fmt.(*fmt).fmtS
0.18s 0.64% 89.25% 0.18s 0.64% fmt.(*fmt).truncate
0.16s 0.57% 89.82% 0.16s 0.57% runtime.memclrNoHeapPointers
0.15s 0.53% 90.35% 1.35s 4.79% fmt.(*pp).fmtString
Для первых 15 видно, что метод сплайсинга fmt является наихудшим, потому что многие методы в fmt ранжируются вверху.buffer
изWriteString
Метод также требует времени.
Приведенный выше ТОП может быть не слишком интуитивным, если посмотреть на флейм-график, то будет понятнее. Лучшее исполнение это+
Сращивание номеров, сращивание соединений и самый медленный сплайсинг fmt.Сварка компоновщика и буферного сплайсинга здесь аналогичны, и они не проявляют свои возможности.
Суммировать
Судя по тесту и анализу всей производительности, ожидаемый нами билдер не сработал, значит ли это, что билдер не практичен? лучше+
Сращивание номеров и соединений? Мы продолжим анализ в следующей статье, и вот некоторые сведения заранее: Например:
- размер объединенной строки
- Количество объединенных строк
Приведенные выше два очень важны, вы можете видеть, к какому из приведенных выше примеров относится.
Что ж, более подробные сведения см. в следующем анализе сплайсинга строк.
Эта статья является оригинальной статьей, перепечатайте ее и укажите источник: «Всегда есть плохие люди, которые удаляют мое первоначальное описание, когда берут статью».
flysnow_org
или сайтwww.flysnow.org/, и впервые прочитал последующие замечательные статьи. «Замечания против гнилых людей **...&*¥» Если вы считаете, что это хорошо, поделитесь им в кругу друзей, спасибо за вашу поддержку.