回 帖 发 新 帖 刷新版面

主题:[原创]看了下面的对比,还有人会用 TC 来编图形程序吗?

差不多每天都有关于 TC 的 graphics 库和 Bios 中断调用画图的问题,好象很多人着迷于用 TC 的 graphics 库和 TC 下的 Bios 中断调用画

图.为什么会这样呢? 我想原因可能在于他们认为 VC 和 Windows 的包装程度高,包装程度高的东西离低层的实现远,接口多,所以用 VC 的类库或 Windows 的 API 做的图形程序性能不如用 TC 的 graphics 库和 Bios 中断调用的图形程序.

老实说,我以前也以为用 VC 做的图形程序性能肯定比不上 TC 做的,但因为一直是做 Windows 程序,为了生产效率也就没有怎么用 TC 画过图,也没想过做个性能对比.

说到这, 真得感谢 wonsea 同志,是他给了我一个机会来纠正我的错误认识. wonsea 在前天的 《putimage 函数》那篇帖子里给出了他用 Bios 中断调用和 graphics 库做的一个鼠标程序, 当时他的程序有点小问题,我就调试了一下他写的程序,运行后我发现鼠标移动快一点时光标就跟不上了,当时我就产生了一个疑问:我在 windows 下写的那些图形程序要移动的对象更多,怎么 TC 的程序反而不如 VC 的程序呢?

于是我就用 Bios 中断调用写了如下一段程序:

//test.cpp
#include<stdio.h>

int main(void)
{
    union REGS  regs,regsa;
    
    regs.h.ah=0x0f;
    int86(0x10,&regs,&regsa);
    
    regs.h.ah=0x00;
    regs.x.ax=0x4f02;
    regs.x.bx=0x105;
    int86(0x10,&regs,&regs);

    struct time beginDraw,endDraw;

    gettime(&beginDraw);
    
    for(long j=0;j<1000;j++)
    {
        for(int i=0;i<600;)
        {
            regs.h.ah=0x0C;
            regs.h.al=60;
            regs.h.bh=0;
            regs.x.cx=j%800;
            regs.x.dx=i;
            int86(0x10,&regs,&regs);
            i++;
        }
    }
    
    gettime(&endDraw);
    getchar();
    
    regs.h.al=regsa.h.al;
    regs.h.ah=0;
    int86(0x10,&regs,&regs);
    
    printf("%hu:%hu\n",beginDraw.ti_sec,beginDraw.ti_hund);
    printf("%hu:%hu",endDraw.ti_sec,endDraw.ti_hund);

    getchar();
    
    return 0;
}

运行结果令我大吃一惊!我居然只看到一些线在屏幕的上半方乱跳!而且 beginDraw 和 endDraw 两个时间居然相差6.53秒,我开始以为是我设的参数 regs.x.bx=0x105 ( 这个参数对应的显示模式是 1024*768 的分辨率,256 色 ) 的问题,于是我把 0x105 改成了 0x104 ( 1024*768 分辨率, 16色),颜色 ( for循环中的参数 regs.x.al ) 取为 8 ,这下还好,总算画出来了,但也用了 6.53 秒, 而且我发现 0x105 和 0x104 都没意义! 因为 TC++3.0 的 int86 函数根本不支持那么高的分辨率.最后我把 0x104 改成了 0x102 ( 600*800 ,16 色 ) ,这下可以填满屏幕了,但同样花了6.53 秒.

天呀,这个速度在我的印象里比 Visual Basic 6 的 pset 方法还要慢的多, 于是我又用 Visual Basic 6 写了下面一段事件句柄:

Private Sub Form_Click()

  Dim i, j, beginTime As Integer
  
   beginTime = Second(Now)
   
   For i = 0 To 10000

       For j = 0 To 600
          PSet (i Mod 800, j)
       Next j
       
   Next i
   
   Me.Cls
   
   Print beginTime
   
   Print Second(Now)
          
      
End Sub

这一下清楚了,我用 Visual Basic 6 做 10 倍的工作,用的时间却只多 1/3 (VB 6 内嵌了真编译器,从那时起VB 6 就告别了解释语言的臭名声).而且编码简单,界面漂亮! VB 6 的 pset 方法都比 TC 的中断调用快 6 倍! 在我的印象中,VB 6 的 pset 方法比 VC++ 6 的 SetPixel ( 也是 windows API) 函数慢将近一半,于是我又用 VC++6 的 SetPixel 方法写了类似的一段 ( 篇幅所限,不帖了),又用 TC graphics 库的 putpixel 写了类似的一段, 结果证明:
      
   [color=0000FF]用 VC++6 或 Win API 函数 SetPixel 画点比用 Bios 中断调用快 10 倍!比 TC 的 putpixel 快 5 倍![/color]

为什么会这样呢?无疑是由于 TC 内嵌的限制太多, 缓冲设定和访问硬件的能力都不如现代编译器! 如果要在 graphics 库和 TC 相关库的基础上改进 TC 的图形库, 必须重写许多东西,其工作量之大,危险性之大让人不敢设想. 除非直接访问显示缓存,进一步加大缓冲区,否则 TC 画图速度无法与 VC 相比! 但你在 TC 中能做的 VC 中都能做( 比如内嵌汇编语言 ), 而且 VC 的起点比 TC 高的多,要想让 TC 在图形方面赶上 VC 的话,恐怕必须对 TC 编译器和缺省库做极大的改动,那还能称为 TC 吗? 幸好 TC 发展成了 Borland C++Builder .

由于VC++.Net2005 的 graphics 对象没有类似的画点函数 ( graphics画点实际上是用画框或画圆的办法画的,但我嫌这种画点方法慢就把 VC++6 中的 SetPixel 从新包装到了我的程序里,因而我在 VC++.Net2005 中的画点速度和 VC++6 差不多),所以我没有用VC++.Net2005 的 graphics 对象做上面的画点程序.

不过我用 VC++.Net2005 写了下面一段事件句柄以比较 VC++.Net2005 的 graphics 对象的 DrawLine 方法和 TC 的 line 函数的工作效率:

    private: System::Void Form1_Click(System::Object^  sender,
               System::EventArgs^  e)
             {
                 Graphics^ g=this->CreateGraphics();
                 
                 DateTime beginDraw=DateTime::Now;
                 
                 Pen^ lp=gcnew Drawing::Pen(Drawing::Color::Red);

                 for(int i=0;i<10000;i++)
                 {
                          g->DrawLine(lp,i%800,0,i%800,600);
                 }

                 DateTime endDraw=DateTime::Now;

                 Drawing::Font^ lf=gcnew Drawing::Font("宋体",20);
                 Brush^ b=Brushes::Blue;

                 g->DrawString(beginDraw.Second.ToString()+":"+
                     beginDraw.Millisecond.ToString(),lf,b,0,50);

                 g->DrawString(endDraw.Second.ToString()+":"+
                     endDraw.Millisecond.ToString(),lf,b,0,200);
                 

             }

对应的 TC 代码如下:

//testa.cpp
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>

int main(void)
{
   int gdriver = DETECT, gmode, errorcode;

   initgraph(&gdriver, &gmode, "");
   errorcode = graphresult();

   if (errorcode != grOk)
   {
      printf("Graphics error: %s\n", grapherrormsg(errorcode));
      printf("Press any key to halt:");
      getch();
      exit(1);
   }

   setcolor(RED);

   struct time beginDraw,endDraw;
   gettime(&beginDraw);

   for(int i=0;i<10000;i++)
      line(i%800,0,i%800,600);

   gettime(&endDraw);

   getch();
   closegraph();

   printf("%hu:%hu\n",beginDraw.ti_sec,beginDraw.ti_hund);
   printf("%hu:%hu\n",endDraw.ti_sec,endDraw.ti_hund);

   getch();

   return 0;
}

这两段代码的对比也挺有意思,VC++的代码短(包装度高),性能好(VC++用了1.09秒,TC用了4.56秒).

那些还在 Dos 下编图形程序的兄弟们,看了上面的对比,痛下决心,马上转到 VC++ 来吧!!!不要怕 VC++ 巨大的类库,VC++IDE 的智能化程度远比 TC 高,调试工具全面,编码效率高的多!



回复列表 (共16个回复)

沙发

有没有在实模式下测TC?

板凳

怎么可以拿 TC 和 VC  比, 根本就没法比
一个是 16 位编译器,一个是 32 位编译器

其外其他也不同意..

3 楼

[quote]怎么可以拿 TC 和 VC&nbsp;&nbsp;比, 根本就没法比
一个是 16 位编译器,一个是 32 位编译器

其外其他也不同意..[/quote]

没考虑那么多,多谢.

不过看那些用TC画图的人,真替他们着急.

4 楼

楼主,你测试TC时程序是在什么环境跑的??
如果是在Windows下跑的当然慢啦....

5 楼

兄弟,我不知道你 DOS下用TC写过游戏吗?就游戏效率而言WINDOS一定是比不上DOS的,就如你所言WINDOWS太多封装和庞大的与设备无关机制,就你说的鼠标,我只能说可能你的写法欠妥担,我们一般是采用33号中断去改变一些变量而在中断外部由程序去响应这些变量,就像WINDOWS中的信号量,互斥量那样,

可能你看到的那位朋友写法欠妥但,一般来说DOS下做的鼠标比在WINDOWS下的鼠标要灵敏和快速,还有就是在高分辨率模式下鼠标的移动可能出现拖影,但采用我刚才说的外部程序响应变量或,不采用类似多线成机制,而采用在循环中处处加载鼠标重画,那DOS下鼠标的效果是太好了~~~

不过我觉得,在很多时候,DOS提供给我们锻炼的空间是WINDOWS编程无法提供的,对于初学编程或靠编程生活吃饭的人来说,我个人觉得WINDOWS编程是我们一定要学,而DOS编程是我们不得不学的,因为在DOS下我们才可能更多的接触低层,弄清楚各种机制的实质,触及编程最核心的部分,只有经过这样的锻炼才能返过头来更好的为我们后面各种技术概念的学习来服务,这样我们才能走的更远,可塑性才能更强啊

个人愚建不知各位大哥是否同意~~

6 楼

别过早地大发议论,

多学习,多接触

7 楼

[quote]兄弟,我不知道你 DOS下用TC写过游戏吗?就游戏效率而言WINDOS一定是比不上DOS的,就如你所言WINDOWS太多封装和庞大的与设备无关机制,就你说的鼠标,我只能说可能你的写法欠妥担,我们一般是采用33号中断去改变一些变量而在中断外部由程序去响应这些变量,就像WINDOWS中的信号量,互斥量那样,

可能你看到的那位朋友写法欠妥但,一般来说DOS下做的鼠标比在WINDOWS下的鼠标要灵敏和快速,还有就是在高分辨率模式下鼠标的移动可能出现拖影,但采用我刚才说的外部程序响应变量或,不采用类似多线成机制,而采用在循环中处处加载鼠标重画,那DOS下鼠标的效果是太好了~~~

不过我觉得,在很多时候,DOS提供给我们锻炼的空间是WINDOWS编程无法提供的,对于初学编程或靠编程生活吃饭的人来说,我个人觉得WINDOWS编程是我们一定要学,而DOS编程是我们不得不学的,因为在DOS下我们才可能更多的接触低层,弄清楚各种机制的实质,触及编程最核心的部分,只有经过这样的锻炼才能返过头来更好的为我们后面各种技术概念的学习来服务,这样我们才能走的更远,可塑性才能更强啊

个人愚建不知各位大哥是否同意~~[/quote]

不敢苟同, TC 接触的硬件再近,它使用的最好也是 286 指令集,内存大小有限制,寄存器大小有限制, 速度有限制,很多硬件加速功能没有使用,其实 TC 没法比  

8 楼

真dos,不是window下,对这些东西的操作会比window快.
不过对于硬件性能的发挥window比dos强.

dos是直接,window是功能强.简单操作(点,线,鼠标操作)之间没有可比性

对于游戏,要说谁快,我肯定的说window程序快.
为什么?呵呵因为完成同样工作的游戏,window提供了更好的硬件支持,虽然
它的开销也不小,不过性能提高肯定比开销大.

9 楼

[quote]兄弟,我不知道你 DOS下用TC写过游戏吗?就游戏效率而言WINDOS一定是比不上DOS的,就如你所言WINDOWS太多封装和庞大的与设备无关机制,就你说的鼠标,我只能说可能你的写法欠妥担,我们一般是采用33号中断去改变一些变量而在中断外部由程序去响应这些变量,就像WINDOWS中的信号量,互斥量那样,

可能你看到的那位朋友写法欠妥但,一般来说DOS下做的鼠标比在WINDOWS下的鼠标要灵敏和快速,还有就是在高分辨率模式下鼠标的移动可能出现拖影,但采用我刚才说的外部程序响应变量或,不采用类似多线成机制,而采用在循环中处处加载鼠标重画,那DOS下鼠标的效果是太好了~~~

不过我觉得,在很多时候,DOS提供给我们锻炼的空间是WINDOWS编程无法提供的,对于初学编程或靠编程生活吃饭的人来说,我个人觉得WINDOWS编程是我们一定要学,而DOS编程是我们不得不学的,因为在DOS下我们才可能更多的接触低层,弄清楚各种机制的实质,触及编程最核心的部分,只有经过这样的锻炼才能返过头来更好的为我们后面各种技术概念的学习来服务,这样我们才能走的更远,可塑性才能更强啊

个人愚建不知各位大哥是否同意~~[/quote]

不同意!!!!!!
什么时代了,还DOS.
DOS对硬件的支持最不好.
游戏效率WINDOWS比不上DOS?
开什么玩笑,大型游戏考虑的问题是多方面的,不可能每个客户都是一样的硬件配置.针对不同硬件配置要求使用相同的代码.这种程序你在DOS下写出来看看有什么效率.
DOS不得不学?????
见鬼了,命令提示符不得不学是真的,DOS不得不学???学了都没地方用.

10 楼

要看运行环境能否充分发挥cpu的性能

同样是操作系统一个是16位,一个是32位
tc的程序只能运行在16为的dos.
当然现在也有32位的 dos!有C的保护模式编译器

我来回复

您尚未登录,请登录后再回复。点此登录或注册