물론 현재 대부분의 프로그램은 (IO) 네트워크 집약적인 프로그램이므로 Python이면 충분합니다. 하지만 기존 프로젝트가 있거나 프로젝트를 개발하려는 경우 컴퓨팅 집약적인 프로그램도 있습니다. . 프로그램 시나리오, 어떻게 해야 할까요?
일부 친구들은 성능 향상을 위해 Python의 계산 집약적인 부분을 다시 작성하기 위해 CC++를 사용하는 Python + CC++에 대해 들어본 적이 있을 것입니다.
물론 이것은 좋은 솔루션이지만 CC++에는 약간의 학습 비용이 든다는 것을 알고 있습니다. 더 나은 솔루션이 있습니까?
/2 Python/
에서 Golang 코드를 호출해 보세요.나중에 운이 좋게도 Golang을 접하게 되었어요. 한동안 사용해 본 후 편집자는 Python에서 Go 코드를 호출할 수 있으면 좋겠다고 생각했습니다. 그 이후에는 정말 CC++를 배우고 싶지 않습니다. CC++ 포인터에는 여전히 몇 가지 임계값이 있으며 스스로 메모리를 해제하는 것은 매우 편리합니다. Go는 자동 가비지 수집 기능이 있고 메모리 누수를 줄여주며 본질적으로 높은 동시성이라는 장점이 있습니다.
지속적으로 정보를 확인하고 몇 가지 함정을 밟은 끝에 노력이 성과를 거두었고 마침내 적합한 방법을 찾았으며 이를 여러분과 공유하고 싶습니다.
현재 가장 널리 사용되는 Python 인터프리터는 CPython입니다. Python은 일부 방법을 통해 Python에서 호출할 수 있는 CC++와 유사한 파일로 컴파일할 수도 있습니다.
/3 테스트 환경/
System: windows
Python 인터프리터: Python 3.7.6(64비트) )
Go 컴파일러: Go 1.14(64비트)
/4 성능 비교/
최적화 효과를 더 잘 반영하기 위해 계산 집약적인 상황에서 두 언어의 차이점을 대략적으로 비교해 보겠습니다.
테스트: 수많은 계산을 시뮬레이션하기 위해 1억(100000000)의 누적을 계산합니다.
1) 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)
아래 그림과 같이 약 10초 정도 소요되는 시간을 확인할 수 있습니다.
2) 코드 이동
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)) }
아래 그림과 같이 약 200ms 정도 소요되는 시간을 확인하실 수 있습니다.
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为例,一个不零不整的数值。
이번에는 결과가 올바른 것을 확인할 수 있습니다. 그런데 왜 100만 개 이상의 결과가 잘못된 걸까요? ? ?
위에서 .so 파일의 계산 결과가 정확하다는 것을 알 수 있습니다. Python이 이를 수신했을 때 변환이 잘못되었을 수도 있습니다. 하지만 걱정하지 마세요. 이 장은 이미 조금 길었습니다. 이 함정은 다음 장에서 확실히 설명할 테니 계속 지켜봐 주세요~
/6 Summary/
위 내용은 [기초] Python+Go - 컴퓨팅 성능을 향상시키는 또 다른 방법을 찾아보자의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!