[Asas] Python+Go - Mari cari cara lain untuk meningkatkan prestasi pengkomputeran

Lepaskan: 2023-07-20 16:35:32
ke hadapan
827 orang telah melayarinya
Hello kawan-kawan, kita semua tahu bahawa Python adalah bahasa yang sangat produktif. Editor sendiri juga sangat menyukai Python. Saya sering menggunakan Python untuk membantu saya menyelesaikan kebanyakan perkara dengan kecekapan tertinggi, tetapi prestasi Python masalah yang selalu kita kecam, terutama GIL kunci besar Kadang-kadang memikirkannya adalah tidak selesa seperti makan lalat.

Sudah tentu, kebanyakan program kami sekarang adalah program intensif rangkaian (IO), dan Python sudah memadai untuk mereka Namun, jika kami mempunyai projek sedia ada atau ingin membangunkan projek, terdapat beberapa yang intensif dari segi pengiraan . Senario program, apakah yang perlu kita lakukan?

Sesetengah rakan mungkin pernah mendengar tentang Python + CC++, menggunakan CC++ untuk menulis semula bahagian Python yang intensif secara pengiraan untuk meningkatkan prestasi.

Sudah tentu, ini adalah penyelesaian yang baik, tetapi kami tahu bahawa CC++ mempunyai beberapa kos pembelajaran. Adakah terdapat penyelesaian yang lebih baik?



/2 Cuba panggil kod Golang dalam Python/

Nanti saya bernasib baik untuk berhubung dengan Golang Selepas menggunakannya untuk beberapa ketika, editor berfikir, bagus jika Python boleh memanggil kod Go Saya tidak mahu belajar CC++ semua, masih terdapat beberapa halangan untuk masuk untuk penunjuk CC++ dan membebaskan memori dengan sendirinya. Ia mempunyai pengumpulan sampah automatik, menjimatkan kebocoran memori, dan mempunyai kelebihan yang sememangnya tinggi.

Selepas sentiasa menyemak beberapa maklumat dan memijak beberapa perangkap, kerja keras membuahkan hasil dan akhirnya saya menemui kaedah yang sesuai, yang saya ingin kongsikan dengan anda.

Jurubahasa Python yang paling banyak digunakan pada masa ini ialah CPython hanya mempunyai modul yang boleh memanggil kod CC++ Melalui beberapa kaedah, Go juga boleh dikompilasi ke dalam fail yang serupa dengan CC++ yang boleh dipanggil oleh Python.


/3 Ujian persekitaran/

System Python penterjemah

:

Python 3.7.6 (64-bit )Go Compiler

:

Go 1.14 (64-bit)


/4 Perbandingan prestasi/

Untuk menggambarkan dengan lebih baik kesan pengoptimuman, kami akan membandingkan secara kasar jurang antara kedua-dua bahasa dalam situasi intensif pengiraan.

Ujian: Kira pengumpulan seratus juta (100000000) untuk mensimulasikan sejumlah besar pengiraan.

1) Kod Python

import time

def run(n):
    sum = 0
    for i in range(n):
        sum += i
    print(sum)


if __name__ == '__main__':
    startTime = time.time()
    run(100000000)
    endTime = time.time()
    print("耗时:", endTime - startTime)
Salin selepas log masuk


Anda boleh melihat penggunaan masa: kira-kira 10s, seperti yang ditunjukkan dalam gambar di bawah.

[Asas] Python+Go - Mari cari cara lain untuk meningkatkan prestasi pengkomputeran


2) Go code

package main

import (
  "fmt"
  "time"
)

func run(n int) {
  sum := 0
  for i := 0; i < n; i++ {
    sum += i
  }
  fmt.Println(sum)
}
func main() {
  var startTime = time.Now()
  run(100000000)
  fmt.Println("耗时:", time.Since(startTime))
}
Salin selepas log masuk


Anda boleh lihat penggunaan masa di bawah: kira-kira 200ms

[Asas] Python+Go - Mari cari cara lain untuk meningkatkan prestasi pengkomputeran


3)测试结论

我们可以看到,在计算方面,Python和Go是有很大的差距的,如果计算这一块能放在Go上就好了。

别着急,马上开始。


/5 Go代码编译为Python可调用的.so文件/

1)Go代码

功能:接收传入的值进行累加,并且返回最终的累加值。

package main

import (
  "C" //C必须导入
)

//export run
func run(n int) int{
  /*
    必须要export 函数名
    //是注释的意思,相当于Python中的 #
    我也是第一次见注释还有作用,黑人三问好???
    固定写法
  */
  sum := 0
  for i := 0; i < n; i++ {
    sum += i
  }
    fmt.Println("我是Go代码,我跑完了,我的结果是:",sum)
  return sum
}

func main() {
  //main函数中什么都不要写,和包名main要对应
}
Salin selepas log masuk


2)编译为.so文件供Python调用。

命令如下:

go build -buildmode=c-shared -o 输出的.so文件 go源文件
Salin selepas log masuk

例如:

go build -buildmode=c-shared -o s1.so s1.go
Salin selepas log masuk


会生成.h文件和.so文件,.so文件供Python调用,如下图所示:

[Asas] Python+Go - Mari cari cara lain untuk meningkatkan prestasi pengkomputeran


3)Ptyhon调用so文件

将上述生成的.so文件复制到Python项目的同一级目录。

[Asas] Python+Go - Mari cari cara lain untuk meningkatkan prestasi pengkomputeran


4)Python代码

依然是计算一个亿,关键部分由Go生成的.so执行。

from ctypes import *
import time


if __name__ == &#39;__main__&#39;:
    startTime = time.time()

    s = CDLL("s1.so")  # 加载s1.so文件
    result = s.run(100000000)  # 调用Go生成的.so文件里面的run函数
    print("result:", result)

    endTime = time.time()
    print("耗时:", endTime - startTime)
Salin selepas log masuk


可以看到耗时:0.11s左右,如下图所示。

[Asas] Python+Go - Mari cari cara lain untuk meningkatkan prestasi pengkomputeran


5)为什么计算的耗时时间不一致,难道是计算错了???

    我们可以看到,虽然速度很快,但是Python在调用Go生成的.so文件之后,拿到的返回值竟然是错的,但是在Go中打印的确实对的,这是为什么呢???

    不要慌,问题不大!我们来计算一次稍微小一点的,上个100w的。


[Asas] Python+Go - Mari cari cara lain untuk meningkatkan prestasi pengkomputeran


额,怎么还是错误。


6)我们再来计算更小一些的数,以10023为例,一个不零不整的数值。

[Asas] Python+Go - Mari cari cara lain untuk meningkatkan prestasi pengkomputeran

Kali ni boleh nampak result dia betul. Tetapi mengapa keputusan 1 juta+ itu salah? ? ?

Kita boleh tahu dari atas bahawa hasil pengiraan fail .so adalah betul Mungkin penukaran itu salah semasa python menerimanya, tetapi jangan risau, bab ini sudah agak panjang, dan. Saya pasti akan menerangkannya dalam bab seterusnya. Perangkap ini akan diselesaikan, jadi nantikan~

/6 Ringkasan/


Mungkin Python+Go bukan yang terbaik dalam meningkatkan prestasi kawasan berbanding dengan Python + CC++, tetapi editor berpendapat bahawa Kaedah ini adalah yang paling bebas bimbang, lagipun, ambang CC++ agak tinggi.
Tetapi setelah berkata demikian, prestasi ini mungkin sudah memadai buat masa ini, Python+Go mungkin beberapa kali lebih cekap daripada Python+CC++.

Atas ialah kandungan terperinci [Asas] Python+Go - Mari cari cara lain untuk meningkatkan prestasi pengkomputeran. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:Go语言进阶学习
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan