len(строка) == 0 или len(строка) ‹ 1

В Go, чтобы проверить, является ли строка пустой, можно использовать:

len(str) == 0

or

len(str) < 1

or

str == ""

В основном это всего лишь счетчик выбора оператора ==, <, !=, но с точки зрения производительности хотите вариант лучше?

Я предполагаю, что == просто сравнивает и не перебирает значения, такие как < или <==, поэтому мне интересно, какой подход лучше всего подходит для этого.


person nbari    schedule 17.01.2016    source источник
comment
Я думаю, вы имеете в виду str == "", а не len(str) != "" (последнее - синтаксическая ошибка)   -  person Filip Haglund    schedule 17.01.2016
comment
Спасибо, только что исправил :)   -  person nbari    schedule 18.01.2016


Ответы (2)


Поскольку пустая строка является нулевым значением строки, вы должны сравнить ее.

str == ""

Проверка переменных на их нулевые значения, чтобы увидеть, пусты ли они, — это способ Go сделать это.

С точки зрения производительности особой разницы нет. Использование len(str) — это вызов функции, поэтому теоретически он должен работать медленнее.

EDIT: некоторые доказательства:

Я сравнил этот код:

func BenchmarkNil(b *testing.B) {
    str := "asd"
    cnt := 0
    for i := 0; i < b.N; i++ {
        if str == "" {
            cnt++
        }
    }
}

с тремя разными проверками в операторе if: str == "", len(str) == 0 и len(str) < 1.

BenchmarkLenEq-8        2000000000               0.77 ns/op
BenchmarkLenLess-8      2000000000               0.76 ns/op
BenchmarkNil-8          2000000000               0.50 ns/op

Для проверки пустой строки (str := "" вместо str := "asd") нет заметной разницы. Проверка на непустую строку занимает больше времени, и там проверка на nil заметно быстрее.

BenchmarkLenEq-8        2000000000               0.34 ns/op
BenchmarkLenLess-8      2000000000               0.33 ns/op
BenchmarkNil-8          2000000000               0.33 ns/op

EDIT2: Единственное, что вы можете сделать в эти дни, чтобы быть в некоторой степени уверенным в том, насколько быстро что-то работает, — это сравнить его. Современные ЦП являются суперскалярными, поэтому один такт на инструкцию просто больше не соответствует действительности. Тестовый код, сравниваемый с пустой строкой, работал на частоте 2,94 ГГц (2,94 * 10 ^ 9 операций в секунду) на моем 4 ГГц 6700k, что составляет менее двух тактовых циклов на итерацию цикла. Нулевая проверка непустой строки выполнялась на частоте 2 ГГц (2*10^9 операций в секунду) на том же процессоре.

Это означает 2 такта ЦП на итерацию цикла при проверке на nil и 3 на проверку длины, или одну инструкцию на итерацию цикла при проверке на пустую строку.

person Filip Haglund    schedule 17.01.2016

Если вы проверите потоки управления ассемблером X86, вы увидите, что есть переход на равенство и перейти на инструкции неравенства. Так что теоретически, и если вы сделаете несколько простых предположений о компиляторе Go, != и < будут работать одинаково (1 такт ЦП).

Если вы действительно в этом заинтересованы, вы можете увидеть этот ответ и сравнить, какая сборка производится для каждого из них.

person mostruash    schedule 17.01.2016