Lua 的速度为什么比 Python 快?
Lua 和 Python 同为虚拟机解释型脚本语言,为什么 Lua 的执行速度比 Python 高?
回复内容:
前面几位已经说的很好,我来做一下补充。@冯东 和 @庞巍伟 都提到了Lua使用的是register-based的虚拟机设计,我看到下面有人评论说既然这种VM的设计性能高,那么为什么Python和java还是使用的stack-based的设计。
我的理解是实现难度吧,register-based的设计中,一个操作需要关注到指令的操作数到底存放在哪里,而stack-based的不需要,它分开了几条指令,首先加载数据到栈顶,然后再进行操作,操作时默认的认为数据就存在栈顶了。(如果不清楚这个过程,可以拖上去看看 @庞巍伟 的回答,就不在这里列出来了)
简单的说,register-based的指令格式设计把stack-based的指令中分几条指令要完成的事情用一条指令搞定了,快当然是快了,难度也加大了。
另外还有一点上面的回答中似乎没有提到,Lua使用的是一遍遍历就生产指令的方式,学过编译原理的,大概都能知道一般分两遍遍历,第一遍生成AST,再一遍遍历AST生成指令,而在Lua中是直接跳过了AST指令这一步的。
还是那句话,快是快了,代码的实现难度也大了些。最早的Lua解释器,也是使用lex、yacc这样的工具来自动生成代码的,后来为了提升性能,作者改成了自己手写的递归下降的分析器。这部分代码是我认为Lua代码中最难理解的一个部分了--因为它要一遍分析干太多的事情了。
我在阅读Lua代码的过程中,能充分感受到作者为了Lua在性能上的提升花费的心血,致敬。 有一些 PUC-Rio Lua(也就是没 JIT 的)和 Python 的 benchmark 对比。结论是 Python 比 C 大约慢 70 倍,Lua 大约慢 30-40 倍。
Lua 是 register-based VM。所谓的寄存器,其实并不神秘,就是 runtime stack 的 topmost frame [1] 是可以被 VM 指令随机访问的。至于为什么 CPU 里的某种硬件也叫寄存器,原因在这里有解释:《什么是寄存器》。
Stack frame 可以被随机访问之后,在同一个 VM 指令里就可以用 native code 一次做很多事情。
可以看云风的这篇 blog:《云风的 BLOG: 虚拟机之比较,lua 5 的实现》
- Stack frame 就是 stack 中属于同一个 function invocation 的所有 stack entries。
最关键的是, lua 是基于寄存器的虚拟机实现,而python还有很多其他脚本语言是基于堆栈的,基于寄存器的虚拟机字节码更简单,更高效,因为register based vm的字节码,一般同时包含了指令/操作数/操作目标等.
对比简单的加法操作:
stack based 生成的字节码大概是这样(仅仅是模拟,不代表实际)
PUSH 1
PUSH 2
ADD // ADD 的操作结果存放eax
PUSH eax // 将结果push入堆栈,以便后面的代码不会覆盖eax
而register based 生成的字节码大概是这样:
ADD 1,2,R1
就一行,R1存放1+2的结果
就这么简答的操作就已经相差4条指令,所以基于寄存器的虚拟机字节码运行更有效率. python的一些设计特性,例如完全面向对象,同时也是它在性能表现上的负担。
举个很简单的例子:
<span class="k">def</span> <span class="nf">test</span><span class="p">():</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">1</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">2</span> <span class="k">return</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span>
lua 最新的5.3 已经支持整数类型, 加上基于寄存器的VM和优秀的编译器, 想慢都难 抛个砖,引个玉。
1. 基于栈和基于寄存器的不同是主要的性能差异原因。这点大家也都解析的非常清楚了,也很好想象。基于栈的求值过程必须使用栈顶的值,想想也知道是反人类的(哦不,反机器的-_-!)。因此会出现很多的push(load)和pop(store)指令,而基于寄存器的指令就一条完事了。但这都是在解释执行的情况下,如果编译到本地指令之后,理论上来说,基于寄存器还是基于栈的实现并没有太多影响,因为都转换成了硬件寄存器,两者的转换过程的开销也没有太多差别。
2. 为什么采用基于栈的虚拟机,除了实现简单(后序遍历AST就有了)之外,占用空间小也是一个基于栈的虚拟机的特点,便于网络传输和嵌入式设备。Java在设计之初就是考虑到网络方面的应用,比如Applet技术,以及嵌入式设备的运用。
3. 个人还有一个想法,不知道是否靠谱@RednaxelaFX。基于栈的虚拟机的指令更加完整地保留了源代码的求值过程,几乎是AST直接『压平』的结果,甚至很容易逆回源代码。这就意味着基于栈的指令在后续操作中可以很容易转换成需要的形式,以便于在不同的形式上做优化。栈代码转换成寄存器代码没有什么效率影响,而寄存器代码转换成栈代码就会出现比遍历AST生成还要多的push(load)和pop(store)指令。栈代码的生成适合直接从AST后续遍历得到,因为求值的过程都是围绕着栈顶。简而言之,栈代码是一个可塑性比较强的代码,先存着,后面想怎么处理都保留了可能性。
4. 语法分析到代码生成过程减少pass数,个人觉得并没有太大的意义。严格来讲这个过程的效率应该不能算是performance的效率,最多只是加快了从源码的启动时间。Performance应该从解释执行开始比较。有的时候单趟编译造成了复杂性反而得不偿失,AST这样的数据结构就适合在上面干该干的事。
5. 实际中虚拟机的效率还和很多其他啊因素有关。比如很重要的方面就是垃圾回收。
6. 至于上升到指令集设计高度的话,不太了解,请R大来。 @RednaxelaFX。他应该会贴个这个传送门虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 Lua的指令集非常非常非常简单,我对着指令说明看了半个小时就能看懂lua的汇编代码了,再花十来分钟就能手动修改lua二进制代码了。而我甚至没完整看过lua的源码。 占坑 以我的观点,最大的关键是在 lua 在语言层面相比 python 简单了很多,所以他们的实现相应的就有了速度的差别。

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



PHP dan Python mempunyai kelebihan dan kekurangan mereka sendiri, dan pilihannya bergantung kepada keperluan projek dan keutamaan peribadi. 1.PHP sesuai untuk pembangunan pesat dan penyelenggaraan aplikasi web berskala besar. 2. Python menguasai bidang sains data dan pembelajaran mesin.

Latihan yang cekap model pytorch pada sistem CentOS memerlukan langkah -langkah, dan artikel ini akan memberikan panduan terperinci. 1. Penyediaan Persekitaran: Pemasangan Python dan Ketergantungan: Sistem CentOS biasanya mempamerkan python, tetapi versi mungkin lebih tua. Adalah disyorkan untuk menggunakan YUM atau DNF untuk memasang Python 3 dan menaik taraf PIP: Sudoyumupdatepython3 (atau SudodnfupdatePython3), pip3install-upgradepip. CUDA dan CUDNN (Percepatan GPU): Jika anda menggunakan Nvidiagpu, anda perlu memasang Cudatool

Membolehkan pecutan GPU pytorch pada sistem CentOS memerlukan pemasangan cuda, cudnn dan GPU versi pytorch. Langkah-langkah berikut akan membimbing anda melalui proses: Pemasangan CUDA dan CUDNN Tentukan keserasian versi CUDA: Gunakan perintah NVIDIA-SMI untuk melihat versi CUDA yang disokong oleh kad grafik NVIDIA anda. Sebagai contoh, kad grafik MX450 anda boleh menyokong CUDA11.1 atau lebih tinggi. Muat turun dan pasang Cudatoolkit: Lawati laman web rasmi Nvidiacudatoolkit dan muat turun dan pasang versi yang sepadan mengikut versi CUDA tertinggi yang disokong oleh kad grafik anda. Pasang Perpustakaan Cudnn:

Docker menggunakan ciri -ciri kernel Linux untuk menyediakan persekitaran berjalan yang cekap dan terpencil. Prinsip kerjanya adalah seperti berikut: 1. Cermin digunakan sebagai templat baca sahaja, yang mengandungi semua yang anda perlukan untuk menjalankan aplikasi; 2. Sistem Fail Kesatuan (Unionfs) menyusun pelbagai sistem fail, hanya menyimpan perbezaan, menjimatkan ruang dan mempercepatkan; 3. Daemon menguruskan cermin dan bekas, dan pelanggan menggunakannya untuk interaksi; 4. Ruang nama dan cgroups melaksanakan pengasingan kontena dan batasan sumber; 5. Pelbagai mod rangkaian menyokong interkoneksi kontena. Hanya dengan memahami konsep -konsep teras ini, anda boleh menggunakan Docker dengan lebih baik.

Python dan JavaScript mempunyai kelebihan dan kekurangan mereka sendiri dari segi komuniti, perpustakaan dan sumber. 1) Komuniti Python mesra dan sesuai untuk pemula, tetapi sumber pembangunan depan tidak kaya dengan JavaScript. 2) Python berkuasa dalam bidang sains data dan perpustakaan pembelajaran mesin, sementara JavaScript lebih baik dalam perpustakaan pembangunan dan kerangka pembangunan depan. 3) Kedua -duanya mempunyai sumber pembelajaran yang kaya, tetapi Python sesuai untuk memulakan dengan dokumen rasmi, sementara JavaScript lebih baik dengan MDNWebDocs. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.

Apabila memilih versi pytorch di bawah CentOS, faktor utama berikut perlu dipertimbangkan: 1. Keserasian versi CUDA Sokongan GPU: Jika anda mempunyai NVIDIA GPU dan ingin menggunakan pecutan GPU, anda perlu memilih pytorch yang menyokong versi CUDA yang sepadan. Anda boleh melihat versi CUDA yang disokong dengan menjalankan arahan NVIDIA-SMI. Versi CPU: Jika anda tidak mempunyai GPU atau tidak mahu menggunakan GPU, anda boleh memilih versi CPU PyTorch. 2. Pytorch versi python

CentOS Memasang Nginx memerlukan mengikuti langkah-langkah berikut: memasang kebergantungan seperti alat pembangunan, pcre-devel, dan openssl-devel. Muat turun Pakej Kod Sumber Nginx, unzip dan menyusun dan memasangnya, dan tentukan laluan pemasangan sebagai/usr/local/nginx. Buat pengguna Nginx dan kumpulan pengguna dan tetapkan kebenaran. Ubah suai fail konfigurasi nginx.conf, dan konfigurasikan port pendengaran dan nama domain/alamat IP. Mulakan perkhidmatan Nginx. Kesalahan biasa perlu diberi perhatian, seperti isu ketergantungan, konflik pelabuhan, dan kesilapan fail konfigurasi. Pengoptimuman prestasi perlu diselaraskan mengikut keadaan tertentu, seperti menghidupkan cache dan menyesuaikan bilangan proses pekerja.

Latihan yang diedarkan Pytorch pada sistem CentOS memerlukan langkah -langkah berikut: Pemasangan Pytorch: Premisnya ialah Python dan PIP dipasang dalam sistem CentOS. Bergantung pada versi CUDA anda, dapatkan arahan pemasangan yang sesuai dari laman web rasmi Pytorch. Untuk latihan CPU sahaja, anda boleh menggunakan arahan berikut: PipinstallToRchTorchVisionTorchaudio Jika anda memerlukan sokongan GPU, pastikan versi CUDA dan CUDNN yang sama dipasang dan gunakan versi pytorch yang sepadan untuk pemasangan. Konfigurasi Alam Sekitar Teragih: Latihan yang diedarkan biasanya memerlukan pelbagai mesin atau mesin berbilang mesin tunggal. Tempat
