【问题标题】:len(string) == 0 or len(string) < 1len(string) == 0 或 len(string) < 1
【发布时间】:2016-01-17 11:28:43
【问题描述】:

在Go,检查字符串是否为空,可以使用:

len(str) == 0

或

len(str) < 1

或

str == ""

基本上只是选择运营商==,&lt;,!=的米,但在性能方面希望选项更好?

我的猜测是 == 只是进行比较,而不是像 &lt; 或 &lt;== 这样的值进行迭代,因此想知道对此的最佳做法是什么。

【问题讨论】:

  • 我想你的意思是str == ""而不是len(str) != ""(最后一个是语法错误)
  • 谢谢,我刚刚修好了:)

标签: go comparison-operators


【解决方案1】:

由于空字符串是字符串的 nil 值,因此您应该与之进行比较。

str == ""

根据它们的 nil 值检查变量以查看它们是否为空是 Go 执行此操作的方式。

在性能方面,没有显着差异。使用len(str)是一个函数调用,所以理论上应该更慢。

编辑:一些证据:

我对这段代码进行了基准测试:

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) &lt; 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: 这些天来,你唯一能做的就是对它进行基准测试。现代 CPU 是超标量的,因此每条指令一个时钟周期根本不再适用。与空字符串进行比较的基准代码在我的 4GHz 6700k 上以 2.94GHz (2.94*10^9 op/s) 运行,每次循环迭代少于两个时钟周期。针对非空字符串的 nil 检查在同一 CPU 上以 2GHz (2*10^9 op/s) 运行。

这意味着在 nil 检查时每次循环迭代需要 2 个 cpu 周期,在 len 检查上需要 3 个 CPU 周期,或者在针对空字符串检查时每次循环迭代需要一条指令。

【讨论】:

    【解决方案2】:

    如果你检查X86 Assembly control flows,你会看到有相等跳转和不相等跳转指令。所以理论上,如果你对 Go 编译器做一些简单的假设,!= 和 &lt; 将执行相同的(1 个 CPU 时钟)。

    如果你真的很感兴趣,你可以查看this answer 并比较它们各自生成的程序集。

    【讨论】:

      猜你喜欢
      • 2019-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      • 2019-02-15
      • 2020-10-28
      • 2015-06-11
      相关资源
      最近更新 更多