在代码优化中使用new运算符是否值得?
Is it worth to use new operator in code optimization?
我有两段代码。第一个代码片段似乎很慢
char* ptrString = "Some string, maximum 4096 characters...";
size_t sLen = strlen(ptrString);
WCHAR* wchrText = new WCHAR[sLen+1];
size_t i;
for(i=0; i<sLen; i++)
{
if ( ptrString[i]=='A' ) break;
wchrText[i] = ptrString[i];
}
//printf(wchrText);
我决定移除strlen
和if
。然后我想到了下面的代码片段
WCHAR* wchrText = new WCHAR[4096];
size_t i=0;
while(ptrString[i] != 'A')
{
wchrText[i] = ptrString[i];
i++;
}
//printf(wchrText);
这里我必须取wchrText, 4096长。我期待有一个更快的执行,但没有任何明显的改善,或者我无法证明!是第二个代码片段中的new操作符降低了速度吗?有没有更好的解决办法?
代码语法和内存使用不重要
啊,你一开始骗了我,这两个循环应该根据编译器和设置优化为相同的代码,但实际上没有任何区别。
one.c:
char* ptrString = "Some string, maximum 4096 characters...";
unsigned int sLen;
char wchrText[4097];
int i;
void one ( void )
{
sLen = 4096;
for(i=0; i<sLen; i++)
{
if ( ptrString[i]=='A' ) break;
wchrText[i] = ptrString[i];
}
}
two.c:
char* ptrString = "Some string, maximum 4096 characters...";
unsigned int sLen;
char wchrText[4097];
int i;
void two ( void )
{
sLen = 4096;
i=0;
while(ptrString[i] != 'A')
{
wchrText[i] = ptrString[i];
i++;
}
}
但他们没有。一个是更多的代码。然后我意识到你的两个循环是不相等的。第二个循环对I变量没有限制检查,它可以通过ram运行超过字符串的长度,直到遇到不应该碰到的字符或找到该字符。
所以当我让这两个例子相同时:
one.c:
char* ptrString = "Some string, maximum 4096 characters...";
unsigned int sLen;
char wchrText[4097];
int i;
void one ( void )
{
sLen = 4096;
for(i=0; /*i<sLen*/; i++)
{
if ( ptrString[i]=='A' ) break;
wchrText[i] = ptrString[i];
}
}
我得到了每个解决方案完全相同的代码,正如预期的那样:
00000000 <one>:
0: e59f3044 ldr r3, [pc, #68] ; 4c <one+0x4c>
4: e59f2044 ldr r2, [pc, #68] ; 50 <one+0x50>
8: e59f0044 ldr r0, [pc, #68] ; 54 <one+0x54>
c: e5931000 ldr r1, [r3]
10: e3a0ca01 mov ip, #4096 ; 0x1000
14: e3a03000 mov r3, #0
18: e582c000 str ip, [r2]
1c: e5803000 str r3, [r0]
20: e5d12000 ldrb r2, [r1]
24: e3520041 cmp r2, #65 ; 0x41
28: 012fff1e bxeq lr
2c: e59fc024 ldr ip, [pc, #36] ; 58 <one+0x58>
30: e7cc2003 strb r2, [ip, r3]
34: e2833001 add r3, r3, #1
38: e5803000 str r3, [r0]
3c: e5f12001 ldrb r2, [r1, #1]!
40: e3520041 cmp r2, #65 ; 0x41
44: 1afffff9 bne 30 <one+0x30>
48: e12fff1e bx lr
如果我修改第二个函数来匹配第一个而不是第一个函数来匹配第二个
two.c:
char* ptrString = "Some string, maximum 4096 characters...";
unsigned int sLen;
char wchrText[4097];
int i;
void two ( void )
{
sLen = 4096;
i=0;
while(ptrString[i] != 'A')
{
wchrText[i] = ptrString[i];
i++;
if(i<sLen) ; break;
}
}
它没有优化到相同的代码,仍然在挠我的头在那一个
忽略内存分配并简单地比较循环性能,在所有条件相同的情况下,无论整数比较花费多少时间,第二个代码片段都会更快。考虑到不超过4096次迭代,我怀疑它会在现代硬件上产生可测量的差异。
, …
如果你不能保证你的源字符串将总是,没有例外,包含一个'A'
字符,那么第二个片段是极其不安全的,因为如果源不包含'A'
,你将超出源和目标数组。更不用说您没有正确地终止目标字符串。
你需要保持长度检查,或者你需要寻找0结束符:
while ( ptrString[i] && ptrString[i] != 'A' )
...
不要忽视安全
相关文章:
- C++矢量复制构造函数和赋值运算符是否也复制保留空间?
- 复合赋值运算符是否不如 C++ 精确?
- 放置新运算符是否会禁用默认的新运算符?
- C++箭头运算符 (->) 是否在所有情况下都返回左值?
- std::unordered_map 运算符 [] 是否对非现有密钥进行零初始化?
- 在这里使用删除运算符是否正确,我很困惑
- lambda 的调用运算符是否需要具有链接?
- 复制构造函数和复制赋值运算符是否应具有相同的语句?
- "new"运算符是否总是调用构造函数?
- 检查运算符是否在C++中过载
- C++新运算符是否在下面使用 malloc()
- 地址运算符是否返回变量引用的对象的地址
- 链表的这个别名运算符是否会产生深度复制
- cv::P oint3f 赋值运算符是否执行"深度"复制?
- 三向比较运算符是否始终有效
- 在全局命名空间中重载不依赖于用户定义类型的标准定义类型的运算符是否格式正确?
- std::string 的运算符<是否应该受到当前区域设置的影响?
- 关于解引用运算符是否在表达式中产生对象对值的定义不明确
- 运算符是否应该==或!=在这种情况下扔
- 检查 QTextStream::运算符>>是否失败