编译原理实验一
一、实验目的
了解程序设计语言的发展历史,了解不同程序设计语言的各自特点;感受编译执行和解释执行两种不同的执行方式,初步体验语言对编译器设计的影响,为后续编译程序的设计和开发奠定良好的基础。
二、实验内容
给定一个特定的功能,分别使用 C/C++、Java、Python、Haskell 和一种汇编语言MASM32实现该功能,对采用这几种语言实现的编程效率,程序的规模,程序的运行效率进行对比分析。分别使用上述几种语言实现一个简单的矩阵乘法程序,输入两个矩阵,输出一个矩阵,并分析相应的执行效果。
MASM32是一种基于x86架构的汇编语言,它是微软公司开发的一种汇编语言。MASM32提供了完整的汇编工具集,包括汇编器、链接器和调试器等,可以用来开发Windows平台下的应用程序。MASM32支持32位和64位汇编,以及各种基本的汇编指令和高级编程技术,是Windows平台下常用的汇编语言之一。
三、实现的具体过程和步骤
- C语言
参考以下帖子配置环境
https://blog.csdn.net/ren648154292/article/details/111151724
编写C语言代码
- Java
参考以下帖子配置环境
https://blog.csdn.net/m0_37220730/article/details/103585266
安装Eclipse,编写JAVA代码
- Python
安装python
1.打开下载好的exe文件,进入python安装界面。
2.勾选Add Python 3.6 to PATH,然后点击Customize installation(自定义安装)
3.选择默认选项,然后点击Next,进行下一步
4.选项默认即可,这里安装路径要改一下,默认的安装路径太深,所以最好把安装路径安置到比较好找的位置。然后点击Install(安装)。
5.安装中
6.安装完成,点击Close关闭
安装并配置Pycharm
创建一个项目后
- Haskell
参考以下网站配置Haskell
https://www.haskell.org/ghcup/
https://blog.csdn.net/Nanzhan_17/article/details/123348982
https://blog.csdn.net/ashtyukjhf/article/details/123862244
编写Haskell程序
编译Haskell程序
D:\WorkSpace>stack exec -- ghc --version
The 'package-indices' key is deprecated in favour of 'package-index'.
The Glorious Glasgow Haskell Compilation System, version 9.2.5
D:\WorkSpace>stack exec -- ghci
The 'package-indices' key is deprecated in favour of 'package-index'.
GHCi, version 9.2.5: https://www.haskell.org/ghc/ :? for help
ghci> :quit
Leaving GHCi.
D:\WorkSpace>stack exec -- where.exe ghc
The 'package-indices' key is deprecated in favour of 'package-index'.
C:\Users\LateSpring\AppData\Local\Programs\stack\x86_64-windows\ghc-9.2.5\bin\ghc.exe
- MASM32
参考以下网站配置环境
https://www.cnblogs.com/onetrainee/p/12093802.html
编写MASM32程序
Link OBJ File以及Assemble & Link
四、运行效果截图
4.1 C/C++
4.2 JAVA
4.3 Python
4.4 Haskell
4.5 MASM32
五、语言易用性和程序规模对比分析
5.1 语言易用性分析
C语言、Java、Python、Haskell和MASM32都是不同类型的编程语言,每种语言都有自己的特点和应用场景。以下是对它们的语言易用性的比较:
- C语言
C语言是一种高级编程语言,其语法规则相对简单,易于学习和理解。C语言的语言构造和基本数据类型较为直接,适合编写系统程序、嵌入式程序和高性能计算等领域的应用。相对于其他编程语言,C语言的执行效率较高,但需要程序员自己负责内存管理和指针操作等细节问题,因此使用C语言开发程序需要具备一定的编程基础和经验。
- Java
Java是一种面向对象的编程语言,具有良好的跨平台性和易用性。Java的语法规则和数据类型相对简单,提供了丰富的类库和API,可以帮助程序员快速开发应用程序。Java的内存管理和异常处理机制较为完善,避免了程序员手动处理这些问题的繁琐过程。因此,Java适合开发Web应用、移动应用、企业级应用等领域的应用。
- Python
Python是一种高级编程语言,具有简洁明了的语法规则和易于理解的数据类型。Python提供了丰富的标准库和第三方库,可以轻松实现各种功能。Python还具有动态类型和自动内存管理的特点,使得程序员可以更专注于代码的逻辑实现而不必过多关注底层细节。Python适合开发数据处理、人工智能、科学计算等领域的应用。
- Haskell
Haskell是一种函数式编程语言,具有函数式编程语言的特点和优势。Haskell的语法规则和数据类型相对严格,需要程序员熟悉函数式编程的思想和范式。Haskell具有强大的类型系统和模式匹配机制,可以帮助程序员在编写程序时尽早发现错误。Haskell适合开发高可靠性和高并发性的应用,例如金融系统、并行计算等。
- MASM32
MASM32是一种汇编语言,需要程序员具备一定的底层硬件知识和编程经验。MASM32的语法规则和数据类型相对简单,但需要程序员自己负责内存管理和指针操作等底层细节。MASM32适合开发操作系统、驱动程序等底层领域的应用,以及需要高性能和精细控制的嵌入式系统应用。
总的来说,每种编程语言都有其自身的优缺点和应用场景。在选择编程语言时,需要根据具体的需求和开发目标进行综合考虑。如果是初学者,建议从易用性和学习难度较低的语言开始学习,例如Python和Java。如果是开发底层系统和高性能应用,可以选择C语言和汇编语言。如果需要高并发性和高可靠性的应用,可以考虑使用函数式编程语言,例如Haskell。
5.2 程序规模对比分析
为除去空行和注释行后的规模
C/C++ | 37 |
---|---|
JAVA | 44 |
Python | 15 |
Haskell | 16 |
MASM32 | 87 |
可以看到Python和Haskell的程序规模特别小,但是Python简洁易学,而Haskell则不那么容易上手。MASM32作为汇编语言,自然规模较大。JAVA的规模也比较大,但是这是因为JAVA有很多底层细节需要考虑,所以编程要求严谨。
六、程序运行性能对比分析
6.1 计算机环境以及配置
6.2 各语言程序运行性能对比分析
- C/C++
在VSCode里输出
2.779000 s, 2.185000 s, 2.158000 s, 3.435000 s, 2.764000 s, 1.931000 s, 1.852000 s, 2.067000 s, 1.524000 s, 1.875000 s
平均时间为2.3871 s
在cmd里输出
3.064000 s, 3.247000 s, 3.264000 s, 3.376000 s, 3.141000 s, 3.547000 s, 3.141000 s, 3.139000 s, 3.157000 s, 3.092000 s
平均时间为3.2085 s
VSCode输出是基于Powershell的,因此虽然比cmd快一点,但还是比较慢。
- JAVA
在Eclipse输出
0.683 s, 0.97 s, 0.891 s, 0.676 s, 0.921 s, 0.802 s, 0.258 s, 0.199 s, 0.647 s, 0.234 s
平均时间为0.6661 s
在cmd里运行
java jisuanjuzheng.MatrixMultiplication
运行.class文件
2.028 s, 2.044 s, 2.07 s, 2.167 s, 2.046 s, 2.098 s, 2.081 s, 2.073 s, 2.124 s, 2.296 s
平均时间为2.101 s
通常情况下,在命令行中输出的速度会比在Eclipse或其他IDE中慢。这是因为IDE会将输出缓存起来,然后在一次性输出到控制台,而在命令行中则会逐行输出,因此速度相对较慢。
- Python
0.9261667728424072 s, 0.8912858963012695 s, 0.8647069931030273 s, 0.809290885925293 s, 0.8172318935394287 s, 0.7363324165344238 s, 0.8806416988372803 s, 0.8605878353118896 s, 0.8349320888519287 s, 0.7833993434906006 s
平均时间为0.8437 s
- Haskell
在VSCode里运行
0.359375 s, 0.296875 s, 0.3125 s, 0.390625 s, 0.359375 s, 0.28125 s, 0.28125 s, 0.328125 s, 0.296875 s, 0.34375 s
平均时间为0.32500 s
在cmd里运行
0.203125 s, 0.234375 s, 0.1875 s, 0.265625 s, 0.234375 s, 0.21875 s, 0.203125 s, 0.265625 s, 0.28125 s, 0.21875 s
平均时间为2.34375 s
- MASM32
在cmd里运行
2.781 s, 2.843 s, 2.859 s, 2.875 s, 2.875 s, 2.969 s, 2.813 s, 3.016 s, 3.094 s, 2.829 s
平均时间为2.8885 s
6.3 总结
在cmd里运行程序的话,都超过了2秒,这是cmd的输出机制(按行输出)造成的。
而在IDE里运行的话,Haskell速度比JAVA快,JAVA比Python快。其他语言的速度差异则不明显。
Haskell程序运行速度为什么比Java快主要有以下几个原因:
函数式编程范式:Haskell采用函数式编程范式,这意味着它更加关注函数的输入输出,而不是过程的细节。这使得Haskell程序具有更高的抽象程度,可以更好地利用现代CPU的内存层次结构,从而获得更高的执行效率。
惰性求值:Haskell采用惰性求值的策略,即只有在需要的时候才会进行计算。这种策略可以避免不必要的计算,从而节省时间和空间。
并发处理:Haskell具有强大的并发处理能力,可以更好地利用多核处理器的优势,从而在多线程和分布式计算方面具有很高的性能表现。
需要注意的是,Haskell与Java是两种不同类型的编程语言,每种语言的使用场景和优缺点也不同。对于特定的问题,Java也可能具有更好的性能表现。Java程序运行速度比Python快的原因主要有以下几点:
编译型语言 vs 解释型语言:Java是一种编译型语言,而Python是一种解释型语言。Java代码需要先被编译成字节码,然后再由Java虚拟机解释执行;而Python代码则在解释器中逐行解释执行。因此,在程序运行时,Java会比Python更快一些。
静态类型语言 vs 动态类型语言:Java是一种静态类型语言,而Python是一种动态类型语言。在编译时,Java编译器可以进行更多的类型检查和优化,从而提高程序的执行效率。而在Python中,由于变量的类型不需要在编写代码时显式声明,因此需要在运行时进行类型推断,这会影响程序的执行速度。
多线程机制:Java提供了强大的多线程机制,可以很容易地实现多线程编程。而Python的线程机制由于全局解释器锁(GIL)的存在,同一时间只能有一个线程在解释器中运行,这对于计算密集型的任务来说,会对程序的执行效率产生一定的影响。
优化算法和虚拟机:Java虚拟机提供了很多优化算法,如垃圾回收、即时编译、内联缓存等,这些算法能够提高程序的执行效率。而Python的解释器没有这些优化算法,所以在程序执行效率上会劣于Java。
需要注意的是,Java和Python都有各自的优点和适用场景。对于某些任务来说,Python的开发效率和易用性可能更优秀,而对于其他任务,Java则可能表现更出色。
但如果不计输出结果矩阵的时间的话C语言和汇编语言应该是最快的。C语言最快,达到了11ms的速度,汇编语言次之,达到了15ms的速度。这是让我比较意外的。
一般情况下,汇编语言的程序运行速度应该比C语言的程序运行速度快,因为汇编语言是底层语言,直接操作计算机的硬件资源,避免了一些高级语言所需要的额外操作和资源调度,能够更加高效地利用计算机的资源。
但是,实际上有些情况下,汇编语言的程序运行速度可能比C语言的程序运行速度慢,这主要是因为汇编语言的程序开发相对复杂,需要手动进行优化,且可能会出现一些不易发现的错误,从而导致程序的性能不如预期。而C语言编译器具有优化能力,可以自动将代码优化为更高效的机器代码,因此在某些情况下,C语言的程序可能会比手写的汇编语言程序运行更快。
综上所述,对于程序的性能来说,编写汇编语言程序可能会比编写C语言程序更具挑战性,需要掌握更深入的计算机原理和硬件操作,并且需要进行更为细致的优化和调试工作。而选择C语言作为编程语言可以获得更高的开发效率和更好的程序性能。
C语言和汇编语言是编译型语言,相对而言可以实现较高的程序运行速度,但编写和调试的难度较大,需要掌握底层的计算机原理和硬件操作。JAVA、Python和Haskell是解释型语言,程序运行速度相对较慢,但编写和调试的难度较低,适合快速开发和迭代。
七、实验心得体会
这次实验,C/C++、JAVA、Python还是比较好配置的,因为以前经常使用。然而,Haskell和MASM32是以前从未接触过的。这就给我的实验造成了一些困难。为了实验的严谨性,同时为了我电脑主机环境的稳定性(就是不想占C盘),我反复斟酌后决定在虚拟机上进行配置。这就意味着我将C/C++、JAVA、Python以及从未接触过的Haskell和MASM32全都在虚拟机配置了一遍(甚至Haskell配置了很多遍)。
而汇编语言的选择也是一个漫长的过程,我询问了很多同学以及在网上寻找相关资料,认为最重要的因素是在windows系统上易于配置和便于测量程序运行的时间。最终才选择了MASM32。期间也考虑了MIPS等汇编语言。感谢我的朋友们在Haskell和汇编语言上带给我的帮助。
不管怎么说,这次的实验收获还是很多。我学习了一些Haskell和汇编语言相关的知识,其中C语言运行还是比汇编快让我大为震撼,在此佩服为C语言编译器优化作出贡献的前辈!我在编写Haskell代码时也感受到了Haskell的思维的新颖。除此之外,我还感受到了编译执行与解释执行在代码规模和运行速度上的不同,熟悉了这些语言的环境配置。