我有这个函数可以在OpenGL
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
的正确和安全的方法是什么?
答案 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
未定义。