C++ 在代码优化中使用新操作符值得吗?
我有两段代码。第一个片段似乎很慢C++ 在代码优化中使用新操作符值得吗?,c++,optimization,C++,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] = p
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);
在这里,我必须采取wchrText,4096长。我本来希望执行速度更快,但没有任何明显的改进,或者我无法证明这一点!是第二段中的新运算符降低了速度吗?有没有更好的解决办法
代码语法和内存使用并不重要。啊,你一开始欺骗了我,这两个循环当然应该根据编译器和设置优化为相同的代码,但实际上没有任何区别 一、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];
}
}
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];
}
}
但他们没有。一个是代码多一点。然后我意识到你的两个循环是不等价的。第二个循环没有对i变量进行限制检查,它可以通过ram运行字符串的长度,直到它碰到不应该碰的东西或找到该字符为止
因此,当我把这两个例子放在一起时:
一、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];
}
}
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
如果我修正了第二个函数来匹配第一个函数,而不是第一个函数来匹配第二个函数,这会很有趣
二、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++;
}
}
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' )
...
不要优化远离安全。CWhy中没有新的操作员。您希望第二个版本更快吗?你仍然在做同样的比较和数据复制。这是怎么编译的呢?printf接受一个char*,但您正在向它传递一个宽char指针。更不用说,如果ptrString不包含a,您的第二个代码段将导致缓冲区溢出。另外,size\u t int i?要按照您希望的方式,根据输入字符串的长度动态分配目标,您需要使用malloc,并且在某一点上是自由的。但是既然你知道字符串的长度有一个最大值,你就可以使用这个值。我在这里使用globals作为防止编译器将所有代码作为死代码删除的一种简单方法。第一个片段使用strlen函数,该函数有一个循环来计算长度。字符串中肯定有一个“A”。链接器在内部将新运算符解析为malloc。C没有新运算符,如果它为你工作,那意味着C编译器在调用C++编译器,或者更可能是C/C++编译器或者你已经做了这一点。如果你试图比较性能,那么这意味着在这两种情况下,字符串都有A,如果是这样,那么优化IIF当然是代码。它的编写方式恰好是在编译时对这两个字符串进行优化,正如这里的示例代码可能根据编译器所做的那样。他们不是阿西娅,他们是阿西娅;