This is Call Rust from Python to speed it up! PyO3 Tutorial: Wrapping a Simple Function Part ➀
It will be a continuation of.
This time,
--Added lib.rs
--Add setup.py
and actually compile
I will continue to do it.
The ultimate goal is
Being able to easily call functions and classes (like things?) Written in rust from python
is.
//lib.Continuation of rs
use pyo3::{wrap_pyfunction};
// ======================CREATING MODULE FOR PYTHON==================================================
/// This module is a python module implemented in Rust.
#[pymodule]
fn test_library(py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(get_prime_numbers))?;
Ok(())
}
here,
#[pymodule]
Decoratortest_library
Declares to be a python module.
And the previous get_prime_numbers
function,
m.add_wrapped(wrap_pyfunction!(get_prime_numbers))?;
Wrapped as a function in that module.
Finally, it is ʻOk (())`, and this module is defined as a function,
PyResult<()>
I'm a little worried that it returns an empty PyResult
(the Void function can be wrapped with this),
I wrote the tutorial as it is, assuming that this area is magical.
We will create the familiar setup.py
that was also used in Cython.
This time it's simple and easy.
setup.py
from setuptools import setup
from setuptools_rust import Binding, RustExtension
setup(name='test_library',
version='0.1',
rust_extensions=[
RustExtension('test_library', 'Cargo.toml',
binding=Binding.PyO3)],
zip_safe=False)
name='test_library',
Can be called from the Python side as ʻimport test_library`.
RustExtension('test_library', 'Cargo.toml',
binding=Binding.PyO3)],
Libraryize the test_library
module in lib.rs
with pyo3
.
At this time, it is very easy to write the dependency to be used as Cargo.toml
. ..
Now that we're ready, let's actually build and call the function from Python.
python setup.py install
And test code
test.py
import test_library
import time
import sys
def get_prime_numbers(n: int):
flags = [True for _ in range(n+2)]
upper = int(n ** 0.5)
for i in range(2, upper+1):
if not flags[i]:
continue
prime = i
j = prime * 2
while j <= n:
flags[j] = False
j += prime
primes = []
for i in range(2, n+1):
if flags[i]:
primes.append(i)
return primes
if __name__ == "__main__":
# just calling rust function from created library
a = 123
b = 456
c = test_library.sum_as_string(a, b)
print(c)
# just calling rust function from created library, to find primes
# rust is (of course) a lot faster than python
# if you wanna call python function, python test.py,
# if you wanna call rust function, python test.py --rust
use_rust = len(sys.argv) == 2 and sys.argv[1] == "--rust"
n = 10000
t1 = time.time()
for _ in range(10):
if use_rust:
primes = test_library.get_prime_numbers(n)
else:
primes = get_prime_numbers(n)
t2 = time.time()
print(f"time took is: {t2-t1} sec")
Quoted from Run Rust module from Python (PyO3)
To execute.
python test.py
Runs a python-based function in
python test.py --rust
Calls a Rust-based function.
result,
$ python test.py
time took is: 0.013466835021972656 sec
$ python test.py --rust
time took is: 0.0005574226379394531 sec
And the difference in execution speed became noticeable.
The ultimate goal is
Being able to easily call functions and classes (like things?) Written in rust from python
It was,
This time I explained how to call a function written in Rust from Python.
The only type conversion I've covered yet is Vec-> List
, so I'll write about other types in the next article. However, the description does not change much, so it is easy.
Also, I would like to write about how to parse Rust class-like things (Struct + method) as class objects on the Python side.
This time around here.
end.
Recommended Posts