`
rybby
  • 浏览: 20102 次
  • 性别: Icon_minigender_1
  • 来自: 玉林
最近访客 更多访客>>
社区版块
存档分类
最新评论

编译语言 vs 解释语言

阅读更多

编译语言 vs 解释语言

阅读:  评论:  作者:Rybby  日期:  来源:rybby.com
一直以为,编译语言的性能绝对比解释语言快,因为就理论而言,解释语言要一边解释(将脚本语言翻译成计算机能识别的语言)一边执行,就工作量来说就比编译语言多一倍。以下是自己心目中长久以来的各种编程语言的性能排行榜:

1)01语言(计算机语言)

2)汇编语言(半计算机语言,低级语言)

3)编译语言(高级语言,如C,C++,C#,JAVA等等)

4)解释语言(脚本语言,如Javascript,VBscript,Node等等)

直到最近,在锐某开发TTD(Thick Text Database/胖文本数据库)的过程中,因为自己是用 Node.js 进行开发的,后来觉得也许用编译语言能获得更高的性能,于是花了几天时间来翻阅C语言的资料,我的电脑磁盘里都保存有各种编程语言的电子书(PDF,CHM,TXT等等),由于自己只用脚本语言开发些网络程序,对软件程序开发没兴趣,所以一直没学这些语言,如果我要设计软件程序,唯一考虑的是汇编语言,很多高级语言都是程序猿为了偷懒而将许多东西封装起来,性能当然大打折扣!本来就打算用汇编来写TTD的,但因为汇编太难学了,只好先学C了。看了几天C的资料,简单入门之后写了个测试程序,结果太坑人啦!编译语言 C 完全输给了解释语言 Node!以下是锐某的测试程序源码:

C语言

程序名:test1.c
#include
#include
void main()
{
unsigned long a = 0, b, *c, d = 1000000000;
time_t t1, t2;
c = &a;
t1 = time(NULL);
for(; a < 1000000000;) a++;
t2 = time(NULL);
b = (t2-t1)*1000;/*以毫秒计算耗时*/
printf("t1 = %lu s\nt2 = %lu s\ntimeDiffer = %lu ms", t1, t2, b);
}

程序名:test2.c
#include
#include
void main()
{
unsigned long a = 0, b, *c, d = 1000000000;
time_t t1, t2;
c = &a;
t1 = time(NULL);
for(; a < d;) a++;
t2 = time(NULL);
b = (t2-t1)*1000;/*以毫秒计算耗时*/
printf("t1 = %lu s\nt2 = %lu s\ntimeDiffer = %lu ms", t1, t2, b);
}

程序名:test3.c
#include
#include
void main()
{
unsigned long a = 0, b, *c, d = 1000000000;
time_t t1, t2;
c = &a;
t1 = time(NULL);
for(; *c < 1000000000;) ++*c;
t2 = time(NULL);
b = (t2-t1)*1000;/*以毫秒计算耗时*/
printf("t1 = %lu s\nt2 = %lu s\ntimeDiffer = %lu ms", t1, t2, b);
}


Node.js

程序名:test1.js
(function test() {
var a = 0, b = 1000000000;
console.time('time');
for(; a < 1000000000;) a++;
console.timeEnd('time');
})()

程序名:test2.js
(function test() {
var a = 0, b = 1000000000;
console.time('time');
for(; a < b;) a++;
console.timeEnd('time');
})()

程序名:test3.js
(function test() {
var a = 0, b = 1000000000, c = Array(1000000000);
console.time('time');
for(; a < c.length;) a++;
console.timeEnd('time');
})()


下面我们来比较结果,所有的例子都反复执行几次,通过目测取平均值,如果要更精确的统计结果至少要执行100次以上,然后取平均值,有兴趣的网友可以自行测试。C程序我是用TC2编译的,至于js程序,大家可以将源码保存为相应的程序名,然后放到Node目录,在Node终端输入如下命令即可:node test1.js

本程序用于计算10亿次加法运算所耗的时间,test1.c 总耗时:35000 ms,每次加法运算耗时 35000*1000*1000/1000000000=35 纳秒(1秒=1*1000毫秒*1000微秒*1000纳秒*1000皮秒*1000飞秒*1000渺秒);test1.js 总耗时:6500 ms,每次加法运算耗时 6.5 纳秒。test2.c 总耗时:60000 ms,每次加法运算耗时 60 纳秒;test2.js 总耗时:5300 ms,每次加法运算耗时 5.3 纳秒,同样的操作,C语言所耗的时间是Node的10多倍!!!这里还仅仅测试了加法的运算而已,如果for循环里还有其它一些表达式语句...
PS:测试PC为神州笔记本优雅Q,CPU:N270,1.60GHZ,内存:1G,很老的机器了。

在测试的过程中发现个有趣的现象,test2.c 所耗的时间是 test1.c 60000/35000=1.7倍,主要原因是 test2.c 用变量“d”来代替实数“1000000000”,使用变量内容的过程是先找到变量的地址才能找到内容,时间就花在这上面了。而Node则刚好相反,test2.js 所耗的时间是 test1.js 5300/6500=0.8倍,Node使用变量反而比实数快!锐某不明白她的变量内容是如何取的,于是又写了 test3.js测试了使用对象属性的耗时,通过实例我们可以看到for循环的耗时按快到慢的排序是:for(;z<变量;) < for(;z<对象的属性(str.length|arr.lenth);) < for(;z<整数;),结果很令人郁闷!因为锐某想象中的排序应该是:for(;z<整数;) < for(;z<变量;) < for(;z<对象的属性(str.length|arr.lenth);),似乎 javascript 中for循环的耗时排序就是按后者排的,这个我没测试过,不过测试了其它一些表达式,如:字符串连接,在 javascript 与 php 中,用 arr.push(str) 比 str += str 要快得多,在不同的浏览器中二者的差别更是明显,比如在 IE 这个臭家伙中,两者的差别简直是一个在天一个在地!但是这些表达式在Node里几乎没有太大的差别。

另外锐某还发现个很惊人的东西,那就是大多数人都以为程序语言自带的函数肯定比程序猿自定义的函数快,因为程序语言自带的函数都经过编译好了,而程序猿自定义的在运行过程中一边解释一边执行,事实是否真如此呢,让我们来一探究竟。我们要将一段字符串转对象,大家常用的都是建立一串json格式的字串,然后用程序自带的函数实现对象化,比如Node里就有这么一个 JSON.parse(),但是锐某自己写的方法却能比这个快至少6倍,原理很简单,我们不需要用json这样垃圾的东西,至少我觉得她很垃圾,不但占空间、耗时间!还很麻烦!因为她用了很多符号,而我们要用这些符号必须经过转义。我们可以用另一种格式:
name^value^name^value^name^value^name^value...
str to obj
var arr, obj, l, z;
arr = str.split('^');
obj = {};
l = arr.length;
for(z = 0; z < l; z+=2) obj[arr[z]] = arr[z+1];

锐某觉得 JSON.parse 之所以慢,应该是她要对每个属性的值都要判断是否还有子对象或属性,时间就是这样被浪费掉了!很多封装的东西都要考虑针对各种各样的情况进行处理,如果我们对自己的数据格式或结构很清晰,根本不需要考虑其它的情况,这样就省下了很多的时间。很多网友一开始学一种语言就库呀、类呀、模块呀什么的,别人写的东西都不一定适合自己用,还是按自己喜欢的方法从底层开始写,那样可以对自己的程序为所欲为的操作。如果对别人的程序不是很了解,在使用过程中出现问题就不知道从哪里开始处理。锐某还是那句话,多走弯路多犯错!这会为你积累非常宝贵的经验!

最后说一下关于C语言的东西,锐某对C不是很了解,呀!应该说完全不了解!鉴于上面的性能测试例子,test2.c 使用 for(; a < d;) 竟然比 test1.c 使用 for(; a < 1000000000;) 慢了1.7倍,仅仅使用了一个变量,就有如此大的差距,如果程序中还用了很多变量呢?出于好奇,我又写了 test3.c 进行测试,这个例子用了指针,但性能跟变量也没有多大差别,或许指针不是这样用的吧?如果不是这样用那应该怎样用?一直很不解,C语言为什么要引入指针这种概念?有种脱裤子放屁的嫌疑,用变量就能取到内容为什么还要绕个圈圈通过指针来取进而增加内存空间。当然如果增加内存空间能带来性能的提升还是可以理解的,因为这个时代是以空间换时间的时代。指针究竟能带来多大的性能?我不知道,我唯一知道的是指针存放变量的地址,通过地址能够快速找到变量的内容,如果用变量就多了找地址这一步。指针到底有哪些优点,希望有大牛写些实例来测试一下,锐某感激不尽!
0
1
分享到:
评论

相关推荐

    解释语言与编译语言的区别

    标题中的“解释语言与编译语言的区别”是一个重要的计算机科学概念,主要涉及到程序设计语言的两种执行模式。这里,我们将详细探讨这两种语言类型的核心特点、工作原理以及它们在实际应用中的差异。 首先,解释语言...

    编译性语言、解释性语言和脚本语言

    计算机编程语言根据其工作原理和执行机制,主要分为编译性语言、解释性语言和脚本语言。这三种类型的编程语言各有特点,适用于不同的场景。 编译性语言,如C、C++、Objective-C和Fortran,它们的源代码首先需要通过...

    编译原理 简单函数绘图语言的解释器

    为简单函数绘图语言编写一个解释器。解释器接受用绘图语言编写的源程序,经语法和语义分析之后,将源程序所规定的图形显示在显示屏(或窗口)中。用编译器编写工具LEX/YACC提供的方式规定绘图语言的词法和语法,用C/...

    编译原理课程解释器构造Java源码

    在这个“编译原理课程解释器构造Java源码”中,我们可以推测这是一个基于Java编程语言实现的解释器项目。Java是一种广泛应用的面向对象的编程语言,它的跨平台特性使得它成为构建各种软件工具的理想选择,包括解释器...

    编译原理课程设计CMM语言解释器

    **编译原理课程设计——CMM语言解释器** 在计算机科学领域,编译原理是研究如何将高级程序设计语言转换为机器可理解的低级语言的一门学科。本项目是基于CMM语言的一个解释器,它由Java语言实现,旨在帮助学生理解和...

    程序设计语言编译原理

    《程序设计语言编译原理》是一门深入探讨计算机科学中编程语言如何被转换为机器可执行代码的学科。编译器是这个领域的核心工具,它将高级编程语言(如C++、Java或Python)编写的源代码转换为特定机器架构的机器语言...

    编译原理——常见名词解释.docx

    解释程序与编译程序类似,但它们不生成目标代码,而是直接解释执行源代码,每读取一行就执行一行,没有预先生成的机器码。自编译是指使用某高级语言编写自己的编译器,而交叉编译则是在一种机器上编译代码,使其能在...

    pascal语言编译解释器的源码

    《Pascal语言编译解释器的源码解析》 Pascal语言,作为一种结构化编程语言,自1970年由Niklaus Wirth教授设计以来,因其清晰的语法和易于理解的特点,在教育和软件开发领域得到了广泛应用。而Pascal语言编译解释器...

    Perl语言的编译

    与其他编程语言不同的是,Perl程序的执行过程中包含了编译和解释两个阶段。这种特性使得Perl能够更好地适应不同的应用场景。本文将详细介绍Perl程序的编译过程,并深入探讨其中的关键概念和技术。 #### Perl程序的...

    程序设计语言编译原理 (陈火旺)

    《程序设计语言编译原理》是陈火旺教授编著的一部编译原理领域的重要教材,它系统地介绍了程序设计语言编译过程中的核心原理与关键技术。该书共分为十二章,每一章都围绕编译技术的一个重要方面展开深入讨论,形成了...

    程序设计语言与编译——语言的设计与实现

    正是在编译技术的支持下,程序设计才从以繁琐的低级语言为工具,发展到以接近自然语言和数学语言的高级程序设计语言为工具,软件开发也从模块化的软件开发方法发展到了面向对象的开发方法。编译技术的发展极大地提高...

    编译原理实验PLMy语言的编译和解释程序及实验报告

    实验标题是“编译原理实验PLMy语言的编译和解释程序及实验报告”,这表明我们将通过实现一个简单的PLMy语言的编译器和解释器来深入理解这一主题。 编译器是将源代码(高级语言)转换为目标代码(机器语言)的程序,...

    编译原理-----函数绘图语言C#版

    函数绘图语言C#版.zip可能是项目源代码的压缩包,包含了实现这个语言的所有文件,包括编译器、解释器、用户界面以及其他支持文件。 总结来说,这个项目提供了一个基于C#的函数绘图工具,它运用了编译原理的理论,...

    E语言模块反编译分析全套源码

    在本资源包中,我们看到的是与E语言模块相关的反编译和分析工作,这对于深入理解E语言的运行机制以及优化代码性能至关重要。反编译是将已编译的二进制代码转换回源代码的过程,这有助于我们查看和理解程序的内部工作...

    编译原理作业_绘图语言解释编译器(含报告).zip

    《编译原理作业_绘图语言解释编译器(含报告)》是一个包含关于编译原理的实践项目,其中可能涵盖了编译器设计与实现的关键概念。编译器是计算机科学中的重要工具,它将高级编程语言转换为机器可执行的指令。在本...

    一个简单语言的编译实例.doc

    本文档提供了一个简单语言的编译实例,展示了编译过程中的各个步骤和关键技术。从文法产生式集合开始,定义了语言的语法结构,然后通过词法分析和语法分析生成 token 序列和符号表,最后生成目标代码程序。 知识点1...

    程序设计语言编译原理(第3版)陈火旺

    本书是在陈火旺、钱家骅、孙永强三位教授编写的《程序设计语言编译原理》的基础上,结合编译技术的最新研究成果和作者多年的教学经验编写而成的。  本书比较全面、系统地介绍了编译程序构造的一般原理和基本实现...

    编译原理复习笔记——把某一种高级语言程序等价地转换成另一种低级语言程序(如汇编语言或机器语言程序)的程序

    编译原理是计算机科学中的一个重要领域,主要关注如何将高级编程语言转换成机器可以理解的低级语言,如汇编语言或机器语言。这个过程涉及多个步骤和复杂的技术,包括词法分析、语法分析、中间代码生成、优化以及目标...

    程序设计语言编译原理(第3版)陈火旺电子书下载

    陈火旺院士所编著的《程序设计语言编译原理(第3版)》是一本在计算机科学领域内极具权威性和影响力的教材。在深入理解计算机程序设计语言以及编译原理方面,这本书是众多高校计算机专业学生和专业人士学习的重要...

    E语言源代码反编译工具-精品

    总的来说,E语言源代码反编译工具是一款针对E语言开发的重要辅助工具,它能帮助用户反编译E语言程序,解析源码,从而提高学习和开发的效率。无论你是E语言的新手还是有经验的开发者,掌握这样的工具都将对你的编程...

Global site tag (gtag.js) - Google Analytics