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当然是代码。它的编写方式恰好是在编译时对这两个字符串进行优化,正如这里的示例代码可能根据编译器所做的那样。他们不是阿西娅,他们是阿西娅;