【问题标题】:What is the fastest way to get seconds passed in cpp?在cpp中获得秒数的最快方法是什么?
【发布时间】:2022-01-20 04:35:52
【问题描述】:

我制作了一个需要尽快循环的因式分解程序。但是,我也想用最少的代码跟踪进度。为此,我通过比较time_t start - time_t end 和递增值marker 每秒显示i 的当前值。

    using namespace std; // cause I'm a noob

    // logic stuff
    int divisor = 0, marker = 0;
    int limit = sqrt(num);
    for (int i = 1; i <= limit; i++) // odd number = odd factors
    {
        if (num % i == 0)
        {
            cout << "\x1b[2K" << "\x1b[1F" << "\x1b[1E"; // clear, up, down
            if (i != 1)
                cout << "\n";
            divisor = num / i;
            cout << i << "," << divisor << "\n";
        }


        end = time(&end); // PROBLEM HERE

        if ((end - start) > marker)
        {
            cout << "\x1b[2K" << "\x1b[1F" << "\x1b[1E"; // clear, up, down
            cout << "\t\t\t\t" << i;
            marker++;
        }
    }

当然,实际代码更加优化并使用boost::multiprecision,但我认为这不是问题所在。当我删除 end = time(&amp;end) 行时,我看到性能提升至少 10%。我只是想知道,如何在不无条件地在每个循环中调用函数的情况下跟踪时间(或至少近似秒数)?还是有更快的功能?

【问题讨论】:

  • 您必须删除所有cout,因为打印总是消耗太多资源。然后,要测量您的功能或算法,最好的方法是使用一些基准工具。你自己不能轻易做到这一点,因为这真的是一项艰苦的工作,这不是你想的那样。有一个在线工具:quick-bench.com
  • @Yves 如果这是关于精确的基准测试,我完全同意你的看法。我认为这是关于可视化的 - 我的回答是基于这个假设。

标签: c++ time


【解决方案1】:

您观察到“当我删除行 end = time(&end) 时,我看到性能提升至少 10%。”我并不感到惊讶,与进行纯 CPU 计算相比,轻松读取时间会占用低效时间。

因此我假设时间读数实际上是消耗掉线时观察到的性能损失的原因。

您可以估计循环在一秒钟内执行的最小迭代次数,然后仅检查该次数的倍数(一半)循环的时间。
即,如果您只想以秒为单位了解时间,那么您应该尝试只稍微多一点地进行耗时的时间读取。

【讨论】:

  • 或者只是暴力破解,每 100 次迭代检查一次。这将开销减少了 99%,仅为 0.1%。
  • @MSalters 我最初打算写 100,是的。但我认为“估计”是一个抽象且仍然易于应用的概念。
【解决方案2】:

我会使用完全不同的方法,将测量/显示代码与循环完全分开,甚至在另一个线程上运行它。 现场演示:https://onlinegdb.com/8nNsGy7EX

#include <iostream>
#include <chrono>           // for all things time
#include <future>           // for std::async, that allows us to run functions on other threads

void function()
{
    const std::size_t max_loop_count{ 500 };
    std::atomic<std::size_t> n{ 0ul };          // make access to loopcounter threadsafe

    // start another thread that will do the reporting independent of the
    // actual work you are doing in your loop.
    // for this capture n (loop counter) by reference (so this thread can look at it)
    auto future = std::async(std::launch::async,[&n, max_loop_count]
    {
        while (n < max_loop_count)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
            std::cout << "\rprogress = " << (100 * n) / max_loop_count << "%";
        }
    });

    // do not initialize n here again. since we share it with reporting    
    for (; n < max_loop_count; n++)
    {
        // do your loops work, just a short sleep now to mimmick actual work
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }

    // synchronize with reporting thread
    future.get();
}

int main()
{
    function();
    return 0;
}

如果您对此示例有任何疑问,请告诉我。

【讨论】:

    猜你喜欢
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2019-10-11
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 2022-12-24
    • 1970-01-01
    相关资源
    最近更新 更多