Какой метод лучше всего подходит для тестирования непустых строк (в Go)?
if len(mystring) > 0 { }
Или:
if mystring != "" { }
Или что-то другое?
Оба стиля используются в стандартных библиотеках Go.
if len(s) > 0 { ... }
можно найти в strconv
пакете: http://golang.org/src/pkg/strconv/atoi.go
if s != "" { ... }
можно найти в encoding/json
пакете: http://golang.org/src/pkg/encoding/json/encode.go
Оба идиоматичны и достаточно понятны. Это больше вопрос личного вкуса и ясности.
Расс Кокс пишет в теме голанг-орехов :
Тот, который делает код понятным.
Если я собираюсь взглянуть на элемент x, я обычно пишу
len (s)> x, даже для x == 0, но если меня волнует
"это конкретная строка", я склонен писать s == "".Разумно предположить, что зрелый компилятор скомпилирует
len (s) == 0 и s == "" в один и тот же эффективный код.
...Сделайте код понятным.
Как указано в ответе Timmmm , компилятор Go генерирует идентичный код в обоих случаях.
if mystring != "" { }
это лучший, предпочтительный и идиоматический способ СЕГОДНЯ. Причина, по которой стандартная библиотека содержит иное, заключается в том, что она была написана до 2010 года, когдаlen(mystring) == 0
оптимизация имела смысл.len
для проверки пустые / непустые строки. Как этот коммит Брэда Фицпатрика. Боюсь, это все еще вопрос вкуса и ясности;)len(v) > 0
в h2_bundle.go (строка 2702). Я полагаю, что он не отображается автоматически, поскольку он генерируется с golang.org/x/net/http2.Это кажется преждевременной микрооптимизацией. Компилятор может создавать один и тот же код для обоих случаев или, по крайней мере, для этих двух
и
потому что семантика явно равна.
источник
Проверка длины - хороший ответ, но вы также можете учесть «пустую» строку, которая также является только пробелом. Не "технически" пусто, но если вы хотите проверить:
источник
TrimSpace
выделит и скопирует новую строку из исходной строки, поэтому этот подход привнесет неэффективность в масштабе.s
тип имеет тип string иs[0:i]
возвращает новую копию. Строки являются неизменяемыми в Go, поэтому нужно ли здесь создавать копию?strings.TrimSpace( s )
не приведет к выделению новой строки и копированию символов, если строка не нуждается в обрезке, но если строка требует обрезки, будет вызвана дополнительная копия (без пробельных символов).gocritic
ЛИНТЕР предлагает использоватьstrings.TrimSpace(str) == ""
вместо проверки длины.Предполагая, что пустые места и все начальные и конечные пробелы должны быть удалены:
Так как :
len("") // is 0
len(" ") // one empty space is 1
len(" ") // two empty spaces is 2
источник
< 1
+1На данный момент компилятор Go генерирует идентичный код в обоих случаях, так что это дело вкуса. GCCGo генерирует другой код, но почти никто не использует его, поэтому я бы не беспокоился об этом.
https://godbolt.org/z/fib1x1
источник
Было бы чище и менее подвержено ошибкам использовать функцию, подобную приведенной ниже:
источник
Просто чтобы добавить больше комментариев
Главным образом о том, как сделать тестирование производительности.
Я провел тестирование со следующим кодом:
И результаты были:
Эффективно варианты обычно не достигают самого быстрого времени, и есть только минимальная разница (около 0,01 нс / оп) между максимальной скоростью варианта.
И если я смотрю полный журнал, разница между попытками больше, чем разница между контрольными функциями.
Также, по-видимому, между BenchmarkStringCheckEq и BenchmarkStringCheckNe или BenchmarkStringCheckLen и BenchmarkStringCheckLenGt и BenchmarkStringCheckLenGt не существует какой-либо ощутимой разницы, даже если последние варианты должны выполняться c 6 раз вместо 2 раз.
Вы можете попытаться получить некоторую уверенность в равной производительности, добавив тесты с измененным тестом или внутренним циклом. Это быстрее:
Это не быстрее
Оба варианта обычно быстрее или медленнее, чем разница между основными тестами.
Также было бы хорошо генерировать тестовые строки (ss), используя генератор строк с соответствующим распределением. И иметь переменную длину тоже.
Так что я не уверен в разнице в производительности между основными методами для тестирования пустой строки в go.
И я могу с уверенностью сказать, что быстрее вообще не тестировать пустую строку, чем тестировать пустую строку. А также быстрее протестировать пустую строку, чем 1 строку символов (префиксный вариант).
источник
Согласно официальным правилам и с точки зрения производительности они выглядят эквивалентно ( ответ ANisus ), s! = "" Будет лучше из-за синтаксического преимущества. s! = "" потерпит неудачу во время компиляции, если переменная не является строкой, в то время как len (s) == 0 пройдет для нескольких других типов данных.
источник
len()
требуется лишь немного больше работы. ОДНАКО, одна вещь, которую мы делали в C, была приведена с левой стороны к aconst
или помещена статическая строка в левую часть оператора, чтобы s == "" не стал s = "", что в синтаксисе C приемлемо. .. и, вероятно, тоже Голанг. (см. расширенный вариант)Это будет более производительным, чем обрезка всей строки, так как вам нужно проверить только один существующий непробельный символ
источник
Я думаю, что лучше всего сравнить с пустой строкой
BenchmarkStringCheck1 проверяется с пустой строкой
BenchmarkStringCheck2 проверяет с нулем len
Я проверяю с пустой и непустой строкой проверки. Вы можете видеть, что проверка с пустой строкой происходит быстрее.
Код
источник