是否值得在代码优化中使用new运算符?

时间:2015-07-08 14:18:16

标签: 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] = ptrString[i];
}
//printf(wchrText);

我决定删除strlenif。然后我想到了以下片段

WCHAR*   wchrText = new WCHAR[4096];
size_t   i=0;
while(ptrString[i] != 'A')
{
    wchrText[i] = ptrString[i];
    i++;
}
//printf(wchrText);

在这里,我不得不接受4096长的wchrText。我期待更快的执行,但没有任何明智的改进,或者我无法证明它!它是第二个代码段中的新运算符,它会降低速度吗?有没有更好的解决方案?

代码语法和内存使用并不重要。

2 个答案:

答案 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' )
   ...

不要优化安全性。