空/空字符串检查:CPU开销

时间:2014-01-29 03:57:55

标签: c++ null cpu-usage cstring overhead

我有这个函数可以在OpenGL

中打印2D文本
void Text2D::printText(const BMfont &font, const char *text, const PenList &pen_list);

我有几个应用程序(游戏)使用了很多,但我从来没有传递空字符串但现在。我使用的string大多数是std::string::c_str()

而且,我有这些变量用于空检查(或空字符串检查)。

    if (text[0] == '\0') return; // # 1
    if (text == '\0') return;  //   # 2
    if (text == nullptr) return; // # 3

这将是调用函数Text2D::printText()

时要执行的第一条指令

除了# 1之外,所有这些检查都会导致CPU使用率约为50%。我很确定这是对我来说这很奇怪。

这3个有什么区别?我认为# 1# 2是相同的,我认为# 3会将nullptr转换为'\0'?为什么# 2# 3会占用过多的CPU费用?检查空C-string的正确和安全的方法是什么?

2 个答案:

答案 0 :(得分:3)

没有办法(1)(单独检查,之后不执行)可以比(2)和(3)更快。可以合理地认为,跟随指针会花费更多的周期,而不仅仅是检查地址值。

检查为x86生成的代码。

if (text == '\0') return -1;  //   # 2

01028C6E cmp dword ptr [text],0
01028C72 jne printText + 29h(01028C79h)
01028C74或eax,0FFFFFFFFh
01028C77 jmp printText + 4Bh(01028C9Bh)

if (text == nullptr) return 0; // # 3

01028C79 cmp dword ptr [text],0
01028C7D jne printText + 33h(01028C83h)
01028C7F xor eax,eax
01028C81 jmp printText + 4Bh(01028C9Bh)

  if (text[0] == '\0') return 1; // # 1

01028C83 mov eax,1
01028C88 imul eax,eax,0
01028C8B mov ecx,dword ptr [text]
01028C8E movsx edx,byte ptr [ecx + eax]
01028C92测试edx,edx
01028C94 jne printText + 4Bh(01028C9Bh)
01028C96 mov eax,1

请注意,如果不检查指针本身,则不应取消引用指针。

答案 1 :(得分:2)

数字1取消引用指针,数字2和3不引用。因此,如果需要从内存中获取指针的目标,我们会期望第一个花费更长的时间。

一般来说,工具非常糟糕,告诉你像这样的微基准测试中发生了什么。

应该注意的是,第一个进入字符串并检查它是否为空;第二个没有。因此,如果这个检查是围绕一些大的复杂代码,那么你看到的任何加速都可能是当字符串为空时跳过该块的结果(不仅是当指针为空时),而不是任何事情要做通过这个测试。

如果你想将null视为空,那么你需要两个测试:

if (str == nullptr || str[0] == '\0') {
    // String is empty
}

因为如果str[0]为nullptr,则str未定义。

相关问题