Heim  >  Artikel  >  Backend-Entwicklung  >  [Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern

[Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern

Go语言进阶学习
Go语言进阶学习nach vorne
2023-07-20 16:35:32814Durchsuche
Hallo Freunde, wir alle wissen, dass Python eine sehr produktive Sprache ist. Ich selbst mag Python auch sehr, um die meisten Dinge mit höchster Effizienz zu erledigen, aber die Leistung von Python ist es Ein Problem, das wir immer kritisiert haben, insbesondere ein großes Schloss. Manchmal ist es genauso unangenehm, darüber nachzudenken, wie eine Fliege zu essen.

Natürlich sind die meisten unserer Programme mittlerweile (IO-)netzwerkintensive Programme, und Python reicht dafür aus. Wenn wir jedoch bestehende Projekte haben oder Projekte entwickeln wollen, gibt es einige, die rechenintensiv sind . Programmszenario, was sollen wir tun?

Einige Freunde haben vielleicht von Python + CC++ gehört, bei dem CC++ verwendet wird, um die rechenintensiven Teile von Python neu zu schreiben, um die Leistung zu verbessern.

Natürlich ist das eine gute Lösung, aber wir wissen, dass CC++ einige Lernkosten mit sich bringt. Gibt es eine bessere Lösung?



/2 Versuchen Sie, Golang-Code in Python aufzurufen/

Nachdem ich das Glück hatte, mit Golang in Kontakt zu kommen, dachte der Redakteur, dass es großartig wäre, wenn Python Go-Code aufrufen könnte Alles in allem gibt es noch einige Eintrittsbarrieren für CC++-Zeiger und das Freigeben von Speicher selbst ist sehr praktisch. Es verfügt über eine automatische Speicherbereinigung, vermeidet Speicherlecks und bietet die Vorteile einer inhärent hohen Parallelität.

Nachdem ich ständig einige Informationen überprüft und auf einige Fallstricke gestoßen bin, hat sich die harte Arbeit gelohnt und ich habe endlich eine geeignete Methode gefunden, die ich gerne mit Ihnen teilen möchte.

Der derzeit am weitesten verbreitete Python-Interpreter ist CPython. Python verfügt lediglich über ein Modul, das CC++-Code aufrufen kann. Über einige Methoden kann Go auch in eine Datei kompiliert werden, die CC++ ähnelt und von Python aufgerufen werden kann.


/3 Testumgebung/

System: Windows

Python-Interpreter: Python 3.7.6 (64-Bit )

Go Compiler: Go 1.14 (64-Bit)


/4 Leistungsvergleich/

Um den Effekt der Optimierung besser widerzuspiegeln, werden wir die Lücke zwischen den beiden Sprachen in rechenintensiven Situationen grob vergleichen.

Test: Berechnen Sie die Akkumulation von einhundert Millionen (100000000), um eine große Anzahl von Berechnungen zu simulieren.

1) Python-Code

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)


Sie können den Zeitverbrauch sehen: etwa 10 Sekunden, wie im Bild unten gezeigt.

[Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern


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))
}


Sie können den Zeitverbrauch sehen: etwa 200 ms, wie in der Abbildung unten gezeigt.

[Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern


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要对应
}


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

命令如下:

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

例如:

go build -buildmode=c-shared -o s1.so s1.go


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

[Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern


3)Ptyhon调用so文件

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

[Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern


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)


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

[Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern


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

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

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


[Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern


额,怎么还是错误。


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

[Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern

Diesmal sieht man, dass das Ergebnis stimmt. Aber warum ist das Ergebnis von 1 Million+ falsch? ? ?

Aus dem Obigen können wir erkennen, dass das Berechnungsergebnis der .so-Datei korrekt ist. Es kann sein, dass die Konvertierung falsch war, als Python sie erhielt. Aber keine Sorge, dieses Kapitel ist schon etwas lang Ich werde es auf jeden Fall im nächsten Kapitel erklären. Bleiben Sie also dran Bereiche im Vergleich zu Python + CC++, aber der Herausgeber ist der Meinung, dass diese Methode die sorgenfreiste ist, schließlich ist die Schwelle von CC++ relativ hoch.

Aber diese Leistung könnte vorerst tatsächlich ausreichen, schließlich ist Python+Go möglicherweise um ein Vielfaches effizienter als Pthon+CC++.

Das obige ist der detaillierte Inhalt von[Grundlagen] Python+Go – Lassen Sie uns einen anderen Weg finden, die Rechenleistung zu verbessern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:Go语言进阶学习. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen