在C和C++中执行时间的差异

8
我最近发现了一个叫Codechef的网站,你可以在那里提交问题的解决方案。 对于一个问题,我分别用C语言和C++语言写了两个答案。这两个代码几乎相同,但是当运行用C语言编写的代码时,它只需要4.89秒,而用C++语言编写的代码却超时了(超过8秒)。这是怎么回事?时间都花在哪里了?
这个问题的输入包含两个正整数n和k(n,k<=107)。接下来的n行输入包含一个正整数ti, 不大于10^9。 输出一个整数,表示有多少个整数ti能被k整除。
Example

Input:
7 3
1
51
966369
7
9
999996
11

Output:
4

我的C代码:

 #include<stdio.h>
   
 int main()  {
   
   int n,k,t;
   scanf("%d %d",&n,&k);
   int i,num=0;
   for(i=0;i<n;i++)  {
     scanf("%d",&t);
     if(t%k==0)  num++;
   }     
   
   printf("%d",num);
    
   return 0;
 }

我的C++代码:

 #include<iostream>
  
 using namespace std;
   
 int main()  {
  
   int n, k, t,num=0;
   cin>>n>>k;
   for(int i=0;i<n;i++)  {
     cin>>t;
     if(t%k==0)  num++;
   }
  
   cout<<num;
   return 0;
 } 

1
首先尝试使用cstdio的C++。 - jacekmigacz
1
@any36 - 那么你的计时包括输入者输入的速度吗?我在C代码中看到了scanf()的调用,在C++代码中看到了cin。这是否包含在计时测试中? - PaulMcKenzie
@PaulMcKenzie:该网站使用预设的测试用例来测试代码。因此,我猜输入不会花费太多时间。 - arry36
你正在使用不同的io调用吗?是否可能使用相同的调用并查看是否类似?如果是,则实际上是cin/out与scanf/printf。至少,您可以使用Cpp编译器编译C代码,然后查看其效果如何。 - aks
@aks:是的,我使用scanf和printf重写了C++代码,实际上比C语言的代码少了0.2秒。 - arry36
显示剩余3条评论
2个回答

28

虽然它们完成相同的任务,但代码并不完全相同。

C++版本使用cin和流,这些默认情况下比scanf等要慢。

默认情况下,cin/cout会浪费时间与C库的stdio缓冲区进行同步,以便您可以自由地在scanf/printf调用中混合使用cin/cout操作。std::ios_base::sync_with_stdio(false);可以关闭此功能。

通过这样做,所需时间可能大致相同。


1
指出 sync_with_stdio 而不是错误的 iostreams are slow,这是一个很好的建议。 - Sebastian Mach
1
基于类型安全的原因,我坚持使用流,但我认识的其他人却不这样做。如果我是你,我不会这样做。在我看来,C++应该像C++一样编写 ;) - const_ref
1
权衡之处在于,C++ 流在每次输入/输出操作后不再与标准 C 流同步,因此理想情况下,您需要选择其中一种,不能混合使用。 - const_ref
1
是的。更多信息请参见此处:http://en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio - const_ref
1
哦!我现在明白了。C++中的所有流都始终处于同步状态。这就是为什么使用流需要更多时间的原因。非常感谢你! :) - arry36
显示剩余6条评论

1
我通常在main()函数后面添加以下3行代码,以便实现更快的输入输出:
ios_base::sync_with_stdio(false);

cin.tie(NULL);

cout.tie(NULL);

所以,试一下这个:
int main()  
{
   ios_base::sync_with_stdio(false);
   cin.tie(NULL);
   cout.tie(NULL);
   int n, k, t,num=0;
   cin>>n>>k;
   for(int i=0;i<n;i++)  {
     cin>>t;
     if(t%k==0)  num++;
   }

   cout<<num;
   return 0;
 } 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接