Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 比memcpy更快地复制以0结尾的字符串_C++_String_Memcpy_Strcpy_Strdup - Fatal编程技术网

C++ 比memcpy更快地复制以0结尾的字符串

C++ 比memcpy更快地复制以0结尾的字符串,c++,string,memcpy,strcpy,strdup,C++,String,Memcpy,Strcpy,Strdup,我有一个关于复制以0结尾的字符串的问题: const char * str = "Hello World !"; size_t getSize = strlen(str); char * temp = new char[getSize + 1]; 。。。我知道我可以使用这个功能 memcpy(temp, str, getSize); 但是我想使用我自己的复制函数,它有这样的动作 int Count = 0; while (str[Count] != '\0') { temp[Coun

我有一个关于复制以0结尾的字符串的问题:

const char * str = "Hello World !";
size_t getSize = strlen(str);
char * temp = new char[getSize + 1];
。。。我知道我可以使用这个功能

memcpy(temp, str, getSize);
但是我想使用我自己的复制函数,它有这样的动作

int Count = 0;
while (str[Count] != '\0') {
    temp[Count] = str[Count];
    Count++;
}
这两种方法都是正确的和成功的。现在我想检查1000万次,然后为memcpy执行此操作

const char * str = "Hello World !";
size_t getSize = strlen(str);
for (size_t i = 0; i < 10000000; i++) {
    char * temp = new char[getSize + 1];
    memcpy(temp, str, getSize);
}
这是我自己的方式

    const char * str = "Hello World !";
    size_t getSize = strlen(str);
    for (size_t i = 0; i < 10000000; i++) {
        char * temp = new char[getSize + 1];
        int Count = 0;
        while (str[Count] != '\0') {
            temp[Count] = str[Count];
            Count++;
        }
    }
第一个过程在420毫秒内完成,第二个过程在650毫秒内完成 ... 为什么?这两种方法都是一样的!我想使用我自己的函数,而不是memcpy。有没有办法让我自己的速度更快,因为memcpy更快,或者更快?我如何更新自己的方式,同时使其更快或与memcpy相同

全源

int main() {

    const char * str = "Hello world !";
    size_t getSize = strlen(str);

    auto start_t = chrono::high_resolution_clock::now();
    for (size_t i = 0; i < 10000000; i++) {
        char * temp = new char[getSize + 1];
        memcpy(temp, str, getSize);
    }
    cout << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start_t).count() << " milliseconds\n";


    start_t = chrono::high_resolution_clock::now();
    for (size_t i = 0; i < 10000000; i++) {
        char * temp = new char[getSize + 1];
        int done = 0;
        while (str[done] != '\0') {
            temp[done] = str[done];
            done++;
        }
    }
    cout << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start_t).count() << " milliseconds\n";

    return 0;
}
结果:

482毫秒 654毫秒

。。。这两种方法都是一样的

不,它们不是:

memcpy不会检查每个字符是否包含“\0”。 实现者所做的优化可能比您天真的方法中所做的要多
您的方法不可能比memcpy更快。

用自己的库函数替换库函数通常会导致性能低下

memcpy代表了一种非常基本的内存操作。因此,作者对其进行了高度优化。与天真的实现不同,库版本在任何可能的情况下一次移动超过一个字节,并在有硬件支持的平台上使用硬件支持

此外,编译器本身知道memcpy和其他库函数的内部工作原理,并且可以在编译时已知长度的情况下完全优化它们


注意:您的实现具有strcpy的语义,而不是memcpy。

看到您没有使用指针,并将您所做的strcpy与memcpy进行比较,这清楚地表明您是一个初学者,正如其他人所说的,很难比编写库的程序员更聪明

但我会给你一些提示来优化你的代码。 我快速看了一下微软的C标准库实现,称为C运行时库,他们在汇编中实现,这比在C中实现要快。所以这是速度的一个方面

在大多数具有32位总线的32位体系结构中,假设数据正确对齐,CPU可以在一个请求到内存的过程中从内存获取32位信息,但即使您需要16位或8位,它仍然需要发出1个请求。因此,使用计算机的字号可能会使您加快速度

最后,我想让您关注SIMD。如果您的CPU提供了它,您可以使用它并获得额外的速度。MSCRT也有一些SSE2优化选项


在过去,我必须不时地编写性能优于我的库实现的代码,因为我有特定的需要或特定类型的数据,我可以对其进行优化,尽管它可能有一些教育价值,除非特别需要,您最好将时间花在实际代码上,而不是花在重新实现库函数上。

如何衡量执行时间?依赖数组末尾的“\0”字符,与memcpy的做法不同。如果您只想处理这种情况,那么使用strcpy可能比使用自己的函数要好,因为在实现中可能会使用某些技巧,使它比您的实现更快。为什么您认为您可以比编译器标准库的创建者更聪明?我敢肯定,新函数的成本使编译器相形见绌复制14字节的成本@许多编译器实现使用汇编语言复制缓冲区的方式。再说一次,为什么你认为你能比业内最好的程序员更聪明?请删除你的答案,并将其作为评论发布。@Khaled.K为什么?我的回答很好地解释了差异。那么memcpy如何创建从str到temp的副本呢?这不是答案,因为你回答的不是问题。@Khaled.K它确实回答了实现是相同的,这怎么会发生?问题好的,我想知道怎么做!!!100%内存也要检查每个字符!要一个接一个地复制。。。所以为什么它必须更快@myOwnWays阅读库实现源代码和/或检查版本优化版本中生成的汇编程序。@myOwnWays memcpy也检查每个字符!嗯?不,它不是。@myOwnWays不,它不是-memcpy是按长度计算的,不是按空终止符计算的。strcpy是按空终止符计算的。