我有两段代码。似乎第一个片段很慢
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);
在这里,我不得不接受4096长的wchrText。我期待更快的执行,但没有任何明智的改进,或者我无法证明它!它是第二个代码段中的新运算符,它会降低速度吗?有没有更好的解决方案?
代码语法和内存使用并不重要。
答案 0 :(得分:0)
啊,你先欺骗我,两个循环应根据编译器和设置优化到相同的代码,但实际上没有任何区别。
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;
}
}
它没有针对相同的代码进行优化,仍然在那个问题上摸不着头脑。
答案 1 :(得分:0)
忽略内存分配并简单地比较循环性能,在所有条件相同的情况下,第二个片段在整数比较所花费的时间上会更快。鉴于迭代次数不超过4096次,我怀疑它会在现代硬件上产生可测量的差异。
<强> BUT 强> ...
如果您无法保证源字符串始终 ,无异常 ,则包含'A'
个字符,那么第二个代码段非常< / em>不安全,因为如果源不包含'A'
,您将超出源数组和目标数组。更不用说你没有正确终止目标字符串。
您需要保持长度检查,或者您需要查找0终止符:
while ( ptrString[i] && ptrString[i] != 'A' )
...
不要优化安全性。