printf比std :: cout快5倍多?

时间:2012-08-20 20:06:20

标签: c++ performance printf cout

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>

int main(int argc, char* argv[])
{
    std::clock_t start;
    double duration;    

    std::cout << "Starting std::cout test." << std::endl;
    start = std::clock();

    for (int i = 0; i < 1000; i++)
    {
        std::cout << "Hello, World! (" << i << ")" << std::endl;
    }

    duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;

    std::cout << "Ending std::cout test." << std::endl;
    std::cout << "Time taken: " << duration << std::endl;

    std::system("pause");

    std::cout << "Starting std::printf test." << std::endl;
    start = std::clock();

    for (int i = 0; i < 1000; i++)
    {
        std::printf("Hello, World! (%i)\n", i);
        std::fflush(stdout);
    }

    duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;

    std::cout << "Ending std::printf test." << std::endl;
    std::cout << "Time taken: " << duration << std::endl;

    system("pause");

    return 0;
}

现在,这是前五次运行的时间:

  • std :: cout test: 1.125 s; printf测试: 0.195 s
  • std :: cout test: 1.154 s; printf测试: 0.230 s
  • std :: cout test: 1.142 s; printf测试: 0.216 s
  • std :: cout test: 1.322 s; printf测试: 0.221 s
  • std :: cout test: 1.108 s; printf测试: 0.232 s

如您所见,使用printf然后fflush比使用std::cout花费的时间少约5倍。

虽然我确实希望使用std::cout的{​​{1}}运算符可能稍微慢一些(几乎是最小的),但我并没有为这个巨大的差异做好准备。我做了一个公平的测试吗?如果是这样,那么是什么让第一次测试比第二次测试慢得多,如果他们基本上做同样的事情呢?

6 个答案:

答案 0 :(得分:12)

试试这个:

#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <iostream>

int main(int argc, char* argv[])
{
#if defined(NOSYNC)
    std::cout.sync_with_stdio(false);
#endif

    std::cout << "Starting std::cout test." << std::endl;

    std::clock_t start = std::clock();

    for (int i = 0; i < 1000; i++)
    {   
        std::cout << "Hello, World! (" << i << ")" << std::endl;
    }   

    clock_t mid = std::clock();

    for (int i = 0; i < 1000; i++)
    {   
        std::printf("Hello, World! (%i)\n", i); 
        std::fflush(stdout);
    }   

    std::clock_t end = std::clock();

    std::cout << "Time taken: P1 " << ((mid-start)*1.0/CLOCKS_PER_SEC) << std::endl;

    std::cout << "Time taken: P2 " << ((end-mid)*1.0/CLOCKS_PER_SEC) << std::endl;


    return 0;
}

然后我得到:

> g++ -O3 t13.cpp
> ./a.out
# lots of lines deleted
Time taken: P1 0.002517
Time taken: P2 0.001872

> g++ -O3 t13.cpp -DNOSYNC   
> ./a.out
# lots of lines deleted
Time taken: P1 0.002398
Time taken: P2 0.001878

因此P2时间不会改变 但是使用std::cout.sync_with_stdio(false);可以改善P1时间(即std :: cout)。因为代码不再试图保持两个流(std :: cout stdout)同步。如果您正在编写纯C ++并且仅使用std :: cout而不是问题。

答案 1 :(得分:9)

要进行真正的苹果对比,请重新编写测试,以便在测试用例之间仅 更改的内容是正在使用的打印函数:

int main(int argc, char* argv[])
{
    const char* teststring = "Test output string\n";
    std::clock_t start;
    double duration;

    std::cout << "Starting std::cout test." << std::endl;
    start = std::clock();

    for (int i = 0; i < 1000; i++)
        std::cout << teststring;
    /* Display timing results, code trimmed for brevity */

    for (int i = 0; i < 1000; i++) {
        std::printf(teststring);
        std::fflush(stdout);
    }
    /* Display timing results, code trimmed for brevity */
    return 0;
}

有了这个,你将只测试printfcout函数调用之间的差异。由于多次<<来电等,您不会产生任何差异。如果您尝试这样做,我怀疑您会得到截然不同的结果。

答案 2 :(得分:3)

使用

func geths() -> Int{
        var sch:Int = 0
        var nam:String = ""
        print("start geths")
        ref.observeSingleEvent(of: .value, with: { (snapshot) in
            if (snapshot.exists()){
                print("snapexist")
                let snapval = snapshot.value as? NSDictionary
                let hs = snapval?["hs"] as? String ?? ""
                let name = snapval?["name"] as? String ?? ""
                if (hs != nil){
                    self.hso = hs
                }else{
                    self.hso = "0"
                }
                if (name != nil){
                    self.nameo = name
                }else{
                    self.nameo = "bob"
                }
                nam = self.nameo
                if let myNumber = NumberFormatter().number(from: self.hso) {
                    let i = myNumber.intValue
                    sch = i
                }else{
                    sch = 0
                }
            }else{
                print("error")
            }
        })
        return sch
    }

防止缓冲。更快

答案 3 :(得分:1)

大约10年前,Scott Meyers测试了 iostream scanf / printf 的效率。取决于编译器和环境,有时scanf / printf比iostream快20%,有时甚至快200%。但iostream从未比scanf / printf更快。根据另外两个给出的例子,scanf / printf仍然比iostream快。 然而,迈耶斯说,#34;在一个非常有用的计划中,没有任何差异。&#34; 根据Google的编程风格([http://google-styleguide.googlecode.com/svn/trunk/cppguide.html]),除了日志记录之外,不应使用流。 iostream的替代品就是自己封装scanf / printf。

答案 4 :(得分:0)

我只有1台计算机的编程范围,所以测试不多。无论如何,std :: cout使用精确的详细代码在我的构建上更快。我正在使用Cpp14。

我只是认为某些人会选择C ++。是的C语言很棒,但从逻辑上讲,我看不出printf如何比std cout更快。 Printf必须在运行时从void指针进行类型转换。 Cout在编译时就这样做了。

答案 5 :(得分:0)

我在运行Windows 10,WSL Ubuntu,CLion 2018,GCC的笔记本电脑上尝试了此测试。没有优化:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>

int main(int argc, char *argv[]) {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::clock_t start;
    double duration1, duration2;

    std::cout << "Starting std::cout test.\n";
    start = std::clock();

    for (int i = 0; i < 100000; i++) {
        std::cout << "Hello, World! (" << i << ")" << std::endl;
    }

    duration1 = (std::clock() - start) / (double) CLOCKS_PER_SEC;

    std::cout << "Starting std::printf test.\n";
    start = std::clock();

    for (int i = 0; i < 100000; i++) {
        std::printf("Hello, World! (%i)\n", i);
        std::fflush(stdout);
    }

    duration2 = (std::clock() - start) / (double) CLOCKS_PER_SEC;

    std::cout << "Time taken: cout " << duration1 << std::endl;
    std::cout << "Time taken Printf: " << duration2 << std::endl;

    return 0;
}

结果:

Test1: Cout: 2.25, Printf: 2.45312  (Cout run first)
Test2: Cout: 2.42188, Printf: 2.07812 (Printf Run first)
Test3: Cout: 2.26562, Printf: 2.25 (Cout run first)
Test4: Cout 2.46875, Printf: 2.57812 (Printf run first)

TL; DR:使用std::ios_base::sync_with_stdio(false)std::cin.tie(nullptr)会使这两个功能几乎处于同一立场。