如何加快上课的循环?使用begin()或循环

发布于 2025-02-13 05:13:05 字数 3691 浏览 1 评论 0原文

如何加快char*/类迭代速度? 我有一些演示代码测试迭代速度。

但是,我不明白为什么使用begin()进行迭代char阵列如此慢,并且在使用for(int = 0; i< n; n; ++ i){ ...}

我正在使用g ++ gnu ++ 2a& MacOS

base :: String是我的自定义类。

代码:

class Iterator {
public:
    const unsigned char *values;
    int n;
    int index = 0;
    Iterator(int n__, const unsigned char *v) {
        n = n__;
        values = v;
    }
    auto& ref() { return *this; }
    auto& ref() const { return *this; }
    auto& begin() { return ref(); }
    auto& cbegin() const { return ref(); }
    auto& end() { return ref(); }
    auto& cend() const { return ref(); }
    bool operator !=(const Iterator& x) { return index < n; }
    bool operator !=(const Iterator & x) const { return index < n; }
    auto& operator ++() { ++index; return ref(); }
};

int main() {
    using namespace cinc;
    using namespace cinc::utils;
    long mark;

    // Itrings.
    print("Speed test:");
    print("   - initialize:");
    mark = timestamp();
    for (int i = 0; i < 10000000; ++i) {
        std::string x;
        x = "";
    }
    print("     - std::string:",timestamp() - mark,"ms");
    mark = timestamp();
    for (int i = 0; i < 10000000; ++i) {
        base::string x;
        x = "";
    }
    print("     - base::string:",timestamp() - mark,"ms");

    // Append.
    print("   - append:");
    mark = timestamp();
    std::string std_string;
    std::string std_string_air;
    for (int i = 0; i < 10000000; ++i) {
        std_string += "0";
    }
    print("     - std::string:",timestamp() - mark,"ms");
    mark = timestamp();
    base::string base_string;
    base_string.allocate();
    base::string base_string_air;
    base_string_air.allocate();
    for (int i = 0; i < 10000000; ++i) {
        base_string.append('0');
    }
    print("     - base::string:",timestamp() - mark,"ms");
    base_string.del();

    // Iterate.
    print("   - iterate:");

    // Iterate std::string with begin.
    mark = timestamp();
    for (auto& i: std_string) {
        std_string_air += i;
    }
    print("     - base::string::begin:",timestamp() - mark,"ms");

    // Iterate base::string with a simlpe for index loop.
    mark = timestamp();
    const unsigned char* us = (unsigned char*)  base_string.values;
    int n = base_string.size__;
    for (int index = 0; index < n; ++index) {
        base_string_air.append(us[index]);
    }
    print("     - base::string::for:",timestamp() - mark,"ms");

    // Iterate base::string with the begin.
    mark = timestamp();
    Iterator iterator = Iterator(base_string.size__, (unsigned char*) base_string.values);
    for (auto& i = iterator.begin(); i != iterator.end(); ++iterator) {
        base_string_air.append(iterator.values[i.index]);
    }
    print("     - base::string::begin:",timestamp() - mark,"ms");
    return 0;

}

输出速度测试:

initialize:
 * std::string: 214 ms
 * base::string: 83 ms
append:
 * std::string: 120 ms
 * base::string: 46 ms
iterate:
 * std::string::begin: 83 ms
 * base::string::for: 22 ms
 * base::string::begin: 94 ms

使用G ++选项'-O2'速度日志:

Speed test:
Speed test:
   - initialize:
     - std::string: 58 ms
     - base::string: 0 ms
   - append:
     - std::string: 96 ms
     - base::string: 10 ms
   - iterate:
     - base::string::begin: 34 ms
     - base::string::for: 0 ms
     - base::string::begin: 0 ms

How can I speed up char*/class iterations?
I have some demo code testing the speed of iterations.

Yet I do not understand why iterating a char array is so slow when using begin(), and much faster when using for (int = 0; i < n; ++i) {...}.

I am using g++ gnu++2a & macos.

base::string is my custom class.

Code:

class Iterator {
public:
    const unsigned char *values;
    int n;
    int index = 0;
    Iterator(int n__, const unsigned char *v) {
        n = n__;
        values = v;
    }
    auto& ref() { return *this; }
    auto& ref() const { return *this; }
    auto& begin() { return ref(); }
    auto& cbegin() const { return ref(); }
    auto& end() { return ref(); }
    auto& cend() const { return ref(); }
    bool operator !=(const Iterator& x) { return index < n; }
    bool operator !=(const Iterator & x) const { return index < n; }
    auto& operator ++() { ++index; return ref(); }
};

int main() {
    using namespace cinc;
    using namespace cinc::utils;
    long mark;

    // Itrings.
    print("Speed test:");
    print("   - initialize:");
    mark = timestamp();
    for (int i = 0; i < 10000000; ++i) {
        std::string x;
        x = "";
    }
    print("     - std::string:",timestamp() - mark,"ms");
    mark = timestamp();
    for (int i = 0; i < 10000000; ++i) {
        base::string x;
        x = "";
    }
    print("     - base::string:",timestamp() - mark,"ms");

    // Append.
    print("   - append:");
    mark = timestamp();
    std::string std_string;
    std::string std_string_air;
    for (int i = 0; i < 10000000; ++i) {
        std_string += "0";
    }
    print("     - std::string:",timestamp() - mark,"ms");
    mark = timestamp();
    base::string base_string;
    base_string.allocate();
    base::string base_string_air;
    base_string_air.allocate();
    for (int i = 0; i < 10000000; ++i) {
        base_string.append('0');
    }
    print("     - base::string:",timestamp() - mark,"ms");
    base_string.del();

    // Iterate.
    print("   - iterate:");

    // Iterate std::string with begin.
    mark = timestamp();
    for (auto& i: std_string) {
        std_string_air += i;
    }
    print("     - base::string::begin:",timestamp() - mark,"ms");

    // Iterate base::string with a simlpe for index loop.
    mark = timestamp();
    const unsigned char* us = (unsigned char*)  base_string.values;
    int n = base_string.size__;
    for (int index = 0; index < n; ++index) {
        base_string_air.append(us[index]);
    }
    print("     - base::string::for:",timestamp() - mark,"ms");

    // Iterate base::string with the begin.
    mark = timestamp();
    Iterator iterator = Iterator(base_string.size__, (unsigned char*) base_string.values);
    for (auto& i = iterator.begin(); i != iterator.end(); ++iterator) {
        base_string_air.append(iterator.values[i.index]);
    }
    print("     - base::string::begin:",timestamp() - mark,"ms");
    return 0;

}

Output speed test:

initialize:
 * std::string: 214 ms
 * base::string: 83 ms
append:
 * std::string: 120 ms
 * base::string: 46 ms
iterate:
 * std::string::begin: 83 ms
 * base::string::for: 22 ms
 * base::string::begin: 94 ms

Speed logs using the g++ option '-O2' during compiling:

Speed test:
Speed test:
   - initialize:
     - std::string: 58 ms
     - base::string: 0 ms
   - append:
     - std::string: 96 ms
     - base::string: 10 ms
   - iterate:
     - base::string::begin: 34 ms
     - base::string::for: 0 ms
     - base::string::begin: 0 ms

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暮倦 2025-02-20 05:13:07

您正在附加到base_string_air。因此,字符串越来越长,将不得不重新分配越来越多的存储空间。

I是带有索引的第一个循环,字符串很小,将其复制到新存储空间很快。在第二个循环中,带有迭代器的字符串更长,并且复制需要更多的时间。

除此之外,您还必须查看编译的代码,以查看是否优化了迭代器抽象。

You are appending to base_string_air. So the string gets longer and longer and will have to reallocate more and more storage.

I the first loop with index the string is small and copying it to the new storage is fast. In the second loop with iterator the string is a lot longer and copying takes more time.

Other than that you have to look at the compiled code to see if your iterator abstraction is optimized away or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文