728x90
반응형
Python With Go
Python 은 쉽고, 깔금하고, 독립적이며, 짧은 시간안에 개발을 할 수 있으며,
수많은 라이브러리들을 사용 할 수 있다는 점에서 좋은 언어 이다.
다만, 파이썬의 장점의 모든 것들은 속도
라는 대가를 가진다.
(numpy 같은 c 라이브러리 제외 하고는...)
pypy 나 pyc 등에 속도 향상을 대체도 있지만 실제 사용해보면 현실은 녹록치 않다.
Go to Python
Go 에서는 Go 를 C에 연결을 혹은 C를 Go에 연결을 도와주는 라이브러리를 제공한다.
https://golang.org/cmd/cgo/
Python 에서는 C 모듈을 가져와서 사용 할 수있는 기능이 있기 때문에
Go도 마찬가지로 사용이 가능하다.
Go .so 파일 만들기
import "C" 와
사용 할 함수에 //export funcName 를 작성하면 된다.
Go 소스
package main
import (
"C"
"fmt"
)
//export Ping
func Ping() {
fmt.Println("Pong")
}
func main() {
}
go build
go build -buildmode=c-shared -o go_library.so main.go
go build 결과
.h 는 Go 와 C 연동을 위해서 datatype 등 adapter
.so 파일은 컴파일된 공유 객체 라이브러리
header ... typedef signed char GoInt8; typedef unsigned char GoUint8; typedef short GoInt16; typedef unsigned short GoUint16; typedef int GoInt32; typedef unsigned int GoUint32; ...
Python 연동
import ctypes
library = ctypes.cdll.LoadLibrary('./go_library.so')
ping = library.Ping
ping()
<CDLL 'C:\Script_Project\my_study\PythonWithGo\source\go_library.so', handle 7ffb7bbc0000 at 0x1ae18fcfc70>
Pong
몇가지 계산 샘플 테스트
package main
import (
"C"
"fmt"
"math/big"
)
//export Ping
func Ping() {
fmt.Println("Pong")
}
//export Factorial
func Factorial(num int) {
var fact big.Int
fact.MulRange(1, int64(num))
fmt.Println(fact.String())
}
//export TotalAdd
func TotalAdd(start, end int) int {
var total int = 0
for i := start; i <= end; i++ {
total += i
}
return total
}
func main() {
}
import timeit
def factorial_go():
import ctypes
library = ctypes.cdll.LoadLibrary('./go_library.so')
library.Factorial.argtypes = [ctypes.c_longlong]
for i in range(10, 20):
library.Factorial(i)
def factorial_python():
import math
for i in range(10, 20):
print(math.factorial(i))
"""
factorial
%timeit -n 10 factorial_go()
84.1 µs ± 25 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit -n 10 factorial_python()
40.6 µs ± 12.2 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
"""
def total_add_go():
import ctypes
library = ctypes.cdll.LoadLibrary('./go_library.so')
library.TotalAdd.argtypes = [ctypes.c_int, ctypes.c_int]
library.TotalAdd(1, 10000)
def total_add_python():
return sum([i for i in range(1, 10000)])
"""
total_add
%timeit -n 10 total_add_go()
82.5 µs ± 148 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit -n 10 total_add_python()
274 µs ± 16.3 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
"""
Python 이 Factorial 부분에서 왜 빠를까?
Python 에서는 Factorial 계산시에 다음과 같은 알고리즘을 사용한다고 한다.
Divide-and-conquer factorial algorithm
Based on the formula and pseudo-code provided at:
http://www.luschny.de/math/factorial/binarysplitfact.html
Faster algorithms exist, but they're more complicated and depend on
a fast prime factorization algorithm.
factorial(n) is written in the form 2**k * m, with m odd.
k and m are computed separately, and then combined using a left shift.
factorial(20) =
(16) *
(8) *
(4 * 12 * 20) *
(2 * 6 * 10 * 14 * 18) *
(1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19)
static PyObject *
math_factorial(PyObject *module, PyObject *arg)
/*[clinic end generated code: output=6686f26fae00e9ca input=6d1c8105c0d91fb4]*/
{
long x, two_valuation;
int overflow;
PyObject *result, *odd_part;
x = PyLong_AsLongAndOverflow(arg, &overflow);
if (x == -1 && PyErr_Occurred()) {
return NULL;
}
else if (overflow == 1) {
PyErr_Format(PyExc_OverflowError,
"factorial() argument should not exceed %ld",
LONG_MAX);
return NULL;
}
else if (overflow == -1 || x < 0) {
PyErr_SetString(PyExc_ValueError,
"factorial() not defined for negative values");
return NULL;
}
/* use lookup table if x is small */
if (x < (long)Py_ARRAY_LENGTH(SmallFactorials))
return PyLong_FromUnsignedLong(SmallFactorials[x]);
/* else express in the form odd_part * 2**two_valuation, and compute as
odd_part << two_valuation. */
odd_part = factorial_odd_part(x);
if (odd_part == NULL)
return NULL;
two_valuation = x - count_set_bits(x);
result = _PyLong_Lshift(odd_part, two_valuation);
Py_DECREF(odd_part);
return result;
}
728x90
반응형
'Python > Python' 카테고리의 다른 글
[Python] DTO, Dataclass Validate 방법 (0) | 2022.07.08 |
---|---|
[Python] 후위표기법(postifx) 계산 코드 (0) | 2022.05.12 |
[Python] __new__ method (0) | 2021.12.23 |
[Python] 파이썬 multiprocessing (0) | 2021.11.25 |
[Python] 파이썬 비동기 I/O (0) | 2021.11.25 |