endl,是真滴慢,建议除天梯赛外统一使用printf

2 comments

  • @ 2022-5-14 17:51:57

    我的建议是: #define endl '\n'

    • @ 2021-12-23 21:59:38

      如果要使用c++的话,建议起步使用双解绑 + 缓冲区策略。

      #define main_begin ios::sync_with_stdio(false);cin.tie(nullptr)
      #define main_end cout<<flush;return 0
      

      将其放到main的开头结尾,其中ios::sync_with_stdio(false)保证与scanf/printf解绑不同步,所以cincout的效率提高但无法与scanf和printf同用甚至无法使用getchar()putchar(c),而需要cin.get()cout << c。由于使用类型判断,处理效率绝对不差于scanf和printf甚至更快,但格式化数据还是考虑使用scanf和printf好。

      对于cin.tie(nullptr)这是为了让cincout在非常短的时间内接连调用的延迟缩短。比如一个for循环中在一行中输入了一个数值,下一行立刻输出该值的一个 O(1)O(1) 函数,不加上这句话效率会非常慢。原因后文提及。

      对于main_end来说,其的作用是将缓冲区输出出来。缓冲区在解绑后必定不会随着输出而刷新。因此,需要特意地进行缓冲区输出cout<<flush。使用cout<<endl也具备这种效果,但是缓冲区频繁刷新会极大降低输出性能(这就是为什么用cin.tie(nullptr)的原因,就是因为不加这一句每次输入输出的切换会刷新缓冲区),这是跑低时长的关键,随着数据量比较大,超过1e6会有明显的一两百ms的差别。所以,使用以下讨论的换行输出方法只会等缓冲区满了才会输出。

      对于换行来说,仅需使用cout << <need_print> << '\n'即可换行,甚至可以自己写一个print/println宏。

      #define print(obj) cout<< obj
      #define println(obj) cout<< obj <<'\n'
      

      注意不可对obj加括号,具体的括号需要内部自己加,比如三目运算符导致的结果就必须加括号,但不能影响obj本身的括号,否则<<符号的类型识别是错误的。

      • 1