只是呼吸 发表于 2010-2-20 16:10:20

多算十六万次乘除法,为什么还快了?

我才开始学习C语言,觉得它确实比VB快。我今天贴一个程序,请高手看看,请多多提意见。
1)问题的提出:我在编写代码时,无意中发现,如果多算了八万次除法、八万次求余,程序输出反而快。如果把这十六万次乘除法去掉,直接输出。结果反而慢。
2)代码如下:
3)说明:程序中的gets()是用来在屏幕上输入大整数的。现在没有用,已将它注释了。为了产生大整数,在程序的开始部分使用了随机数发生器。打双横线的部分就是。这里产生的是四万位的十进制大整数。#include <stdio.h>
#include <string.h>//*以下程序是我自己编写的验证超大数组的输出,已通过VC++6.0编译。
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <windows.h>

void main()
{
long t1,t2;//------------时间变量。

   char a,b;
        long c;
        int i,j,k,l,m,s,kd,kf;
        register temp,n;//------寄存器变量,听说可以不这样定义。
unsigned int seed; //-----------初始化随机函数的发生器
//        printf("输入第一个数:");
//                       gets(a);//-----从屏幕输入一个大数。
///        printf("输入第二个数::");
//                      gets(b);//-----从屏幕输入一个大数。



   
   
   
t1=GetTickCount();//时间计时开始;

seed=time(0);//=======以下部分用来随机产生两个大数,共产生两个四
    srand(seed);//======万位的大整数。
a=2;
for(kd = 1; kd <=40000; kd++)
   {
        a=rand();
       a=abs(a);
           a%=10;
}
   b=6;
    for(kf = 1; kf <=40000; kf++)
   {
        b=rand();
       b=abs(b);
           b%=10;

}

           i=40001;//strlen(a);//计算输入数组中的数字位数。
   j=40001;//strlen(b);
////====================以上部分是随机产生两个四万位的大整数。


       //i=strlen(a);//计算输入数组中的数字位数。
           //j=strlen(b);
               


             for(s=0;s<=i+j-1;s++)//将数组C初始化,让C中的数置零。
               {
                       c=0;
               }
               


for (k=0;k<=i-1;k++)//*以下就是乘法的核心部分,这是最垃圾最慢的乘法。
        // 这里的目的不是为了检验乘法算法的优劣。就
   //姑且用之吧*/
{
   temp=a-48;
   for (n=0;n<=j-1;n++)
   c+=temp*(b-48);//遍乘B中的各数。结果保存在C中。
   }



for(l=i+j-1;l>=1 ;--l)//---------B
{//---------------------------------B
c+=c/10;//把C中的十位以上数字取出来,准备向前进位。B
c%=10;       //-------------------------B
   }//--------------------------------------B

       
for (m=0;m<=i+j-2;m++)//这两句是输出语句。把乘积的结果输出。
   printf("%d",c);//输出语句。
                       
        printf("\n");

t2=GetTickCount();//程序段结束后取得系统运行时间(ms)。时间计时结束。

    printf("时间%d",t2-t1);

}
将程序中注有B的那五行用上,程序输出时间是13秒多(在我的机器上),而将程序中注有B的那五行去掉,程序输出的时间是16秒多。这是为什么?

gxqcn 发表于 2010-2-21 08:27:00

请问是否是相同的测试环境?比如:
有否运行其它程序?如打开网页、听MP3?
是否有后台程序活跃?如磁盘整理、杀毒扫描等?

计时最好是多运行几次再进行统计,否则容易得出错误结果误导判断。

只是呼吸 发表于 2010-2-21 09:33:32

能得到郭老大的回答非常高兴。
回老大:1)没有其它的程序在运行,我连杀毒软件都没有安装。
         2)这两种运行情况分别各运行上百次。不是一次。但多加那几行程序就少要时间。

只是呼吸 发表于 2010-2-21 09:52:24

回#gxqcn
我刚才又试了(分别两种情况各10次),将网线也拨了。只有VC++6.0和上面的那个程序在运行。仍然是16秒多和13秒多的时差。我还找了个秒表,秒表测出来的时间也是多算的要快。

gxqcn 发表于 2010-2-21 10:11:32

debug 模式 还是 release 模式?

〇〇 发表于 2010-2-21 10:22:54

cl /O2 m.c
注释//B
cl /O2 m1.c

D:\app>type t1.bat
@echo off
time < cr
m >m.obj
time < cr
m1 >m.obj
time < cr
m1 >m.obj
time < cr
m >m.obj
time < cr


D:\app>t1
当前时间: 10:21:47.74
输入新时间:
当前时间: 10:21:49.81
输入新时间:
当前时间: 10:21:51.87
输入新时间:
当前时间: 10:21:53.95
输入新时间:
当前时间: 10:21:55.99
输入新时间:

〇〇 发表于 2010-2-21 10:24:47

输出的长度不同导致
D:\app>m> m.obj

D:\app>m1> m1.obj

D:\app>dir m*obj
驱动器 D 中的卷没有标签。
卷的序列号是 98F7-F781

D:\app 的目录

2010-02-2110:23            80,014 m.obj
2010-02-2110:24         628,341 m1.obj

只是呼吸 发表于 2010-2-21 11:11:28

引用:5#gxqcndebug 模式 还是 release 模式?
回郭老大:是debug模式。
引用:6#、7#   输出的长度不同导致
                  D:\app>m> m.obj
回这位老大:你写的代码我看不懂,但你给的结论“输出的长度不同导致”让我真的明白了。是真正的理解了。那个乘法执行完以后,数组中全是没有进位的大数,其实际数字个数远远超过十六万个数。而计算机输出多的数字可能就慢了。当把这些进位全部处理完毕。数组中只剩下十六万个数字。所以看上去快了。

再次感谢各位老大在百忙之中关注我的问题。谢谢。

szsdk 发表于 2010-4-3 19:52:38

有没有什么能精确测试程序运行时间的程序啊?

只是呼吸 发表于 2010-4-4 23:08:33

有没有什么能精确测试程序运行时间的程序啊?
szsdk 发表于 2010-4-3 19:52 http://bbs.emath.ac.cn/images/common/back.gif
可能没有,现在通常的做法只是大概测一下程序的运行时间。
页: [1] 2
查看完整版本: 多算十六万次乘除法,为什么还快了?