Bien sûr, la plupart de nos programmes sont désormais des programmes (IO) gourmands en réseau, et Python leur suffit. Cependant, si nous avons des projets existants ou si nous souhaitons développer des projets, certains nécessitent beaucoup de calculs. . Scénario du programme, que devons-nous faire ?
Certains amis ont peut-être entendu parler de Python + CC++, utilisant CC++ pour réécrire les parties gourmandes en calcul de Python afin d'améliorer les performances.
Bien sûr, c'est une bonne solution, mais nous savons que CC++ a des coûts d'apprentissage. Existe-t-il une meilleure solution ?
/2 Essayez d'appeler le code Golang en Python/
Plus tard, j'ai eu la chance d'entrer en contact avec Golang. Après l'avoir utilisé pendant un moment, l'éditeur s'est dit que ce serait génial si Python pouvait appeler du code Go. Je ne veux vraiment pas apprendre CC++. dans l'ensemble, il existe encore des barrières à l'entrée pour les pointeurs CC++ et libérer de la mémoire par vous-même est très pratique. Il dispose d'un garbage collection automatique, évite les fuites de mémoire et présente les avantages d'une concurrence intrinsèquement élevée.
Après avoir constamment vérifié certaines informations et marché sur quelques écueils, le travail acharné a payé et j'ai enfin trouvé une méthode adaptée, que j'aimerais partager avec vous.
L'interpréteur Python le plus utilisé à l'heure actuelle est CPython. Python n'a qu'un module qui peut appeler du code CC++ Grâce à certaines méthodes, Go peut également être compilé dans un fichier similaire à CC++ qui peut être appelé par Python.
/3 Environnement de test/
Système : windows
Interpréteur Python : Python 3.7.6 (64 bits )
Go Compilateur : Go 1.14 (64 bits)
/4 Comparaison des performances/
Afin de mieux refléter l'effet de l'optimisation, nous comparerons grossièrement la différence entre les deux langages dans des situations à forte intensité de calcul.
Test : Calculez l'accumulation de cent millions (100000000) pour simuler un grand nombre de calculs.
1) Code 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)
Vous pouvez voir la consommation de temps : environ 10 s, comme indiqué dans l'image ci-dessous.
2) Allez coder
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)) }
Vous pouvez voir la consommation de temps : environ 200 ms, comme le montre la figure ci-dessous.
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要对应 }
命令如下:
go build -buildmode=c-shared -o 输出的.so文件 go源文件
例如:
go build -buildmode=c-shared -o s1.so s1.go
会生成.h文件和.so文件,.so文件供Python调用,如下图所示:
依然是计算一个亿,关键部分由Go生成的.so执行。
from ctypes import * import time if __name__ == '__main__': 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)
我们可以看到,虽然速度很快,但是Python在调用Go生成的.so文件之后,拿到的返回值竟然是错的,但是在Go中打印的确实对的,这是为什么呢???
不要慌,问题不大!我们来计算一次稍微小一点的,上个100w的。
额,怎么还是错误。
6)我们再来计算更小一些的数,以10023为例,一个不零不整的数值。
Cette fois, vous pouvez constater que le résultat est correct. Mais pourquoi le résultat de plus d’un million est-il faux ? ? ?
Nous pouvons savoir par ce qui précède que le résultat du calcul du fichier .so est correct. Il se peut que la conversion ait été erronée lorsque python l'a reçu, mais ne vous inquiétez pas, ce chapitre est déjà un peu long, et Je l'expliquerai certainement dans le prochain chapitre. Ce piège sera résolu, alors restez à l'écoute ~
/6 Summary/
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!