Crowdstrike瀟ããã®èå³æ·±ãç 究ã®ç¿»èš³ãããªãã®æ³šæã«ãããããŸãããã®è³æã¯ãïŒãã«ãŠã§ã¢åæã«é¢é£ããŠïŒããŒã¿ãµã€ãšã³ã¹ã®åéã§ã®Rustèšèªã®äœ¿çšã«ç¹åããŠãããçŽç²ãªPythonã¯èšããŸã§ããªããNumPyãSciPyã§ãRustããã®ãããªåéã§ã©ã®ããã«ç«¶äºã§ãããã瀺ããŠããŸãã
èªæžã楜ããïŒ
Pythonã¯æã人æ°ã®ããããŒã¿ãµã€ãšã³ã¹ããã°ã©ãã³ã°èšèªã®1ã€ã§ãããããã«ã¯ååãªçç±ããããŸããPython Package IndexïŒPyPIïŒã«ã¯ãNumPyãSciPyãNatural Language ToolkitãPandasãããã³Matplotlibãªã©ã®èšå€§ãªããŒã¿ãµã€ãšã³ã¹ã©ã€ãã©ãªããããŸããé«å質ã®åæã©ã€ãã©ãªãè±å¯ã«ãããåºç¯ãªéçºè ã³ãã¥ããã£ãååšããPythonã¯ãå€ãã®ããŒã¿ãµã€ãšã³ãã£ã¹ãã«ãšã£ãŠæãããªéžæè¢ã§ãã
ãããã®ã©ã€ãã©ãªã®å€ãã¯ããã©ãŒãã³ã¹äžã®çç±ããCããã³C ++ã§å®è£ ãããŠããŸãããé¢æ°ãPythonããåŒã³åºããããã«å€éšé¢æ°ã€ã³ã¿ãŒãã§ã€ã¹ïŒFFIïŒãŸãã¯Pythonãã€ã³ãã£ã³ã°ãæäŸããŠããŸãããããã®äœã¬ãã«èšèªã®å®è£ ã¯ãç¹ã«å®è¡æéãšã¡ã¢ãªæ¶è²»ã®ç¹ã§ãPythonã®æãç®ã«èŠããæ¬ ç¹ã®ããã€ãã軜æžããããšãç®çãšããŠããŸããå®è¡æéãšã¡ã¢ãªæ¶è²»ãå¶éã§ããå Žåãã¹ã±ãŒã©ããªãã£ã¯å€§å¹ ã«ç°¡çŽ åãããŸããããã¯ãã³ã¹ããåæžããããã«éèŠã§ããããŒã¿ãµã€ãšã³ã¹ã®åé¡ã解決ããé«æ§èœã®ã³ãŒããèšè¿°ã§ããã°ããã®ãããªã³ãŒããPythonãšçµ±åããããšã¯å€§ããªå©ç¹ã«ãªããŸããããŒã¿ãµã€ãšã³ã¹ãšãã«ãŠã§ã¢åæã®
亀差ç¹ã§äœæ¥ããå Žå é«éãªå®è¡ã ãã§ãªããã¹ã±ãŒãªã³ã°ã®ããã®å ±æãªãœãŒã¹ã®å¹ççãªäœ¿çšãå¿ èŠã§ããã¹ã±ãŒãªã³ã°ã¯ãè€æ°ã®ãã©ãããã©ãŒã ã«ãããæ°çŸäžã®å®è¡å¯èœãã¡ã€ã«ãå¹ççã«åŠçãããªã©ãããã°ããŒã¿ã®éèŠãªåé¡ã®1ã€ã§ããææ°ã®ããã»ããµã§è¯å¥œãªããã©ãŒãã³ã¹ãå®çŸããã«ã¯ã䞊ååŠçãå¿ èŠã§ããéåžžããã«ãã¹ã¬ããã䜿çšããŠå®è£ ãããŸããããããã³ãŒãå®è¡ãšã¡ã¢ãªæ¶è²»ã®å¹çãæ¹åããããšãå¿ èŠã§ãããã®ãããªåé¡ã解決ããå ŽåãããŒã«ã«ã·ã¹ãã ã®ãªãœãŒã¹ã®ãã©ã³ã¹ããšãããšã¯é£ããããã«ãã¹ã¬ããã·ã¹ãã ãæ£ããå®è£ ããããšã¯ããã«å°é£ã§ãã Cããã³C ++ã®æ¬è³ªã¯ãã¹ã¬ããã»ãŒããæäŸãããªãããšã§ããã¯ãããã©ãããã©ãŒã åºæã®å€éšã©ã€ãã©ãªããããŸãããã¹ã¬ããã®å®å šæ§ãä¿èšŒããããšã¯æããã«éçºè ã®çŸ©åã§ãã
ãã«ãŠã§ã¢ã® 解æã¯æ¬è³ªçã«å±éºã§ããæªæã®ãããœãããŠã§ã¢ã¯ãå€ãã®å Žåãæå³ããªãæ¹æ³ã§ãã¡ã€ã«åœ¢åŒã®ããŒã¿æ§é ãæäœãããããåæãŠãŒãã£ãªãã£ãæ©èœããªããªããŸãã Pythonã§ç§ãã¡ãåŸ ã£ãŠããæ¯èŒçäžè¬çãªèœãšãç©Žã¯ãåªããåå®å šæ§ã®æ¬ åŠã§ãã
None
ãã®å Žæbytearray
ã§æåŸ
ããããšãã«å¯å€§ã«å€ãåãå
¥ããPythonã¯ãå®å
šãªæ··ä¹±ã«é¥ãããšãã§ããŸããããã¯ãã³ãŒãã«ã®ãã§ãã¯ãè©°ã蟌ãããšã«ãã£ãŠã®ã¿åé¿ã§ããŸãNone
ããã®ãããªãããã¯ã¿ã€ãã³ã°ãã®ä»®å®ã¯ããã°ãã°ã¯ã©ãã·ã¥ãåŒãèµ·ãããŸãã
ããããéããããŸããRustã¯ãäžã§æŠèª¬ãããã¹ãŠã®æœåšçãªåé¡ã«å¯Ÿããçæ³çãªãœãªã¥ãŒã·ã§ã³ãšããŠãããŸããŸãªæ¹æ³ã§äœçœ®ä»ããããŠããŸããã©ã³ã¿ã€ã ãšã¡ã¢ãªã®æ¶è²»ã¯Cããã³C ++ã«å¹æµããåºç¯ãªåå®å šæ§ãæäŸãããŸããRustã¯ãã¡ã¢ãªã®å®å šæ§ã匷åã«ä¿èšŒããå®è¡æã®ãªãŒããŒãããããªããªã©ã®è¿œå ã®ã¢ã¡ããã£ãæäŸããŸãããã®ãããªãªãŒããŒãããããªããããRustã³ãŒããä»ã®èšèªãç¹ã«Pythonã®ã³ãŒããšçµ±åããã®ãç°¡åã«ãªããŸãããã®èšäºã§ã¯ãRustã«ã€ããŠç°¡åã«èª¬æããããã«é¢é£ããèªå€§å®£äŒã«å€ãããã©ããã確èªããŸãã
ããŒã¿ãµã€ãšã³ã¹ã®ãµã³ãã«ã¢ããªã±ãŒã·ã§ã³
ããŒã¿ãµã€ãšã³ã¹ã¯ãå€ãã®å¿çšåŽé¢ãæã€éåžžã«åºãäž»é¡é åã§ãããããããã¹ãŠã1ã€ã®èšäºã§èª¬æããããšã¯äžå¯èœã§ããããŒã¿ãµã€ãšã³ã¹ã®ç°¡åãªã¿ã¹ã¯ã¯ããã€ãã·ãŒã±ã³ã¹ã®æ å ±ãšã³ããããŒãèšç®ããããšã§ãããããã§ãšã³ããããŒãèšç®ããããã®äžè¬åŒã¯ã§äžããããããŠã£ãããã£ã¢ïŒ
ã©ã³ãã å€æ°ã®ãšã³ããããŒãèšç®ããããã«
X
ããŸãåå¯èœãªãã€ãå€ãçºçããåæ°ãã«ãŠã³ããã次ãã§ç¹å®ã®å€ã«ééãã確çãèšç®ããããã«ééããèŠçŽ ã®ç·æ°ã«ãã£ãŠãã®æ°ãåå²ãããããã次ã«ãç¹å®ã®å€xiãçºçãã確çã®å éåããã®è² ã®å€ãšãããããç¬èªã®æ
å ±ãã«ãŠã³ãããŸã... ããã§ã¯ãããåäœã§ãšã³ããããŒãèšç®ããŠãããããããã§äœ¿çšããŠããŸãïŒãããã®å Žåã¯åºæ°2ã«æ³šæïŒã
Rustãè©ŠããŠãRustããšã³ããããŒèšç®ãšçŽç²ãªPythonãã©ã®ããã«åŠçããããããã³äžèšã®äžè¬çãªPythonã©ã€ãã©ãªã®ããã€ããèŠãŠã¿ãŸããããããã¯ãRustã®æœåšçãªããŒã¿ãµã€ãšã³ã¹ããã©ãŒãã³ã¹ã®ç°¡ç¥åãããèŠç©ããã§ãããã®å®éšã¯ãPythonãPythonã«å«ãŸããŠããåªããã©ã€ãã©ãªã«å¯Ÿããæ¹å€ã§ã¯ãããŸããããããã®äŸã§ã¯ãPythonããã€ã³ããŒãã§ããRustã³ãŒãããç¬èªã®Cã©ã€ãã©ãªãçæããŸãããã¹ãŠã®ãã¹ãã¯Ubuntu 18.04ã§å®è¡ãããŸããã
ãã¥ã¢ãã€ãœã³
æšæºã©ã€ãã©ãªã®æ°åŠã¢ãžã¥ãŒã«ã®ã¿ã䜿çšããŠã
entropy.py
ãšã³ããããŒãèšç®ããããã®
åçŽãªçŽç²ãªPythoné¢æ°ïŒc ïŒããå§ããŸãããbytearray
ããã®é¢æ°ã¯æé©åãããŠããªããããå€æŽãšããã©ãŒãã³ã¹æž¬å®ã®éå§ç¹ãšããŠäœ¿çšããŸãã
import math
def compute_entropy_pure_python(data):
"""Compute entropy on bytearray `data`."""
counts = [0] * 256
entropy = 0.0
length = len(data)
for byte in data:
counts[byte] += 1
for count in counts:
if count != 0:
probability = float(count) / length
entropy -= probability * math.log(probability, 2)
return entropy
NumPyããã³SciPyã䜿çšããPython
åœç¶ã®ããšãªãããSciPyã¯ãšã³ããããŒãèšç®ããæ©èœãæäŸããŸãããã ããæåã«ã
unique()
NumPyã®é¢æ°ã䜿çšããŠãã€ãé »åºŠãèšç®ããŸããSciPyå®è£
ã«ã¯çžå¯Ÿãšã³ããããŒïŒã«ã«ããã¯ã©ã€ãã©ãŒè·é¢ïŒãèšç®ããããã®è¿œå æ©èœããããããSciPyãšã³ããããŒé¢æ°ã®ããã©ãŒãã³ã¹ãä»ã®å®è£
ãšæ¯èŒããããšã¯å°ãäžå
¬å¹³ã§ããç¹°ãè¿ãã«ãªããŸãããPythonããã€ã³ããŒããããã³ã³ãã€ã«æžã¿ã®Rustã©ã€ãã©ãªã®ããã©ãŒãã³ã¹ã確èªããããã«ãïŒããŸãé
ããªãããšãé¡ã£ãŠïŒãã¹ããã©ã€ããè¡ããŸããã¹ã¯ãªããã«å«ãŸããŠããSciPyå®è£
ã䜿çšããŸãentropy.py
ã
import numpy as np
from scipy.stats import entropy as scipy_entropy
def compute_entropy_scipy_numpy(data):
""" bytearray `data` SciPy NumPy."""
counts = np.bincount(bytearray(data), minlength=256)
return scipy_entropy(counts, base=2)
Rustã䜿çšããPython
次ã«ãå ç¢ã§ããããã«ã以åã®å®è£ ãšæ¯èŒããŠãRustå®è£ ãããå°ã詳ããèŠãŠãããŸããCargoã§çæãããããã©ã«ãã®ã©ã€ãã©ãªããã±ãŒãžããå§ããŸãããã次ã®ã»ã¯ã·ã§ã³ã§ã¯ãRustããã±ãŒãžãã©ã®ããã«å€æŽãããã瀺ããŸãã
cargo new --lib rust_entropy
Cargo.toml
Cargo.toml
Cargoããã±ãŒãžãå®çŸ©ããã©ã€ãã©ãªåãæå®ãã
å¿
é ã®ãããã§ã¹ããã¡ã€ã«ããå§ããŸã rust_entropy_lib
ãRust Package Registryã®crates.ioããå
¥æã§ãããããªãã¯cpythonã³ã³ãããŒïŒv0.4.1ïŒã䜿çšããŸãããã®èšäºã§ã¯ãå·çæç¹ã§å
¥æå¯èœãªææ°ã®å®å®çãªãªãŒã¹ã§ããRust v1.42.0ã䜿çšããŠããŸãã
[package] name = "rust-entropy"
version = "0.1.0"
authors = ["Nobody <nobody@nowhere.com>"] edition = "2018"
[lib] name = "rust_entropy_lib"
crate-type = ["dylib"]
[dependencies.cpython] version = "0.4.1"
features = ["extension-module"]
lib.rs
Rustã©ã€ãã©ãªã®å®è£ ã¯éåžžã«ç°¡åã§ããçŽç²ãªPythonã®å®è£ ãšåæ§ã«ãå¯èœãªãã€ãå€ããšã«countsé åãåæåããããŒã¿ãå埩åŠçããŠã«ãŠã³ããèšå®ããŸããæäœãå®äºããã«ã¯ã確çãæãã確çã®è² ã®åèšãèšç®ããŠè¿ããŸãã
use cpython::{py_fn, py_module_initializer, PyResult, Python};
///
fn compute_entropy_pure_rust(data: &[u8]) -> f64 {
let mut counts = [0; 256];
let mut entropy = 0_f64;
let length = data.len() as f64;
// collect byte counts
for &byte in data.iter() {
counts[usize::from(byte)] += 1;
}
//
for &count in counts.iter() {
if count != 0 {
let probability = f64::from(count) / length;
entropy -= probability * probability.log2();
}
}
entropy
}
ããš
lib.rs
ã¯ãPythonããçŽç²ãªRusté¢æ°ãåŒã³åºãã¡ã«ããºã ã ãã§ãããçŽç²ãªãRusté¢æ°ãåŒã³åºãlib.rs
ããã®CPython調æŽ(compute_entropy_cpython())
é¢æ°ãå«ããŸã(compute_entropy_pure_rust())
ãããããããšã§ãåäžã®çŽç²ãªRustå®è£
ãç¶æããCPythonã«é©ããã©ãããŒãæäŸããããšããã®ã¿å©çãåŸãããŸãã
/// Rust CPython
fn compute_entropy_cpython(_: Python, data: &[u8]) -> PyResult<f64> {
let _gil = Python::acquire_gil();
let entropy = compute_entropy_pure_rust(data);
Ok(entropy)
}
// Python Rust CPython
py_module_initializer!(
librust_entropy_lib,
initlibrust_entropy_lib,
PyInit_rust_entropy_lib,
|py, m | {
m.add(py, "__doc__", "Entropy module implemented in Rust")?;
m.add(
py,
"compute_entropy_cpython",
py_fn!(py, compute_entropy_cpython(data: &[u8])
)
)?;
Ok(())
}
);
PythonããRustã³ãŒããåŒã³åºã
æåŸã«ãPythonããïŒåã³ããã
entropy.py
ïŒRustå®è£
ãåŒã³åºããŸãããããè¡ãã«ã¯ããŸãRustããã³ã³ãã€ã«ãããç¬èªã®åçã·ã¹ãã ã©ã€ãã©ãªãã€ã³ããŒãããŸãã次ã«ãpy_module_initializer!
Rustã³ãŒãã®ãã¯ãã䜿çšããŠPythonã¢ãžã¥ãŒã«ãåæåãããšãã«æå®ãããæäŸãããŠããã©ã€ãã©ãªé¢æ°ãåŒã³åºãã ãã§ãããã®æ®µéã§ã¯entropy.py
ããšã³ããããŒèšç®ã®ãã¹ãŠã®å®è£
ãåŒã³åºãé¢æ°ãå«ãPythonïŒïŒã¢ãžã¥ãŒã«ã1ã€ã ããããŸãã
import rust_entropy_lib
def compute_entropy_rust_from_python(data):
"" bytearray `data` Rust."""
return rust_entropy_lib.compute_entropy_cpython(data)
Cargoã䜿çšããŠãUbuntu 18.04ã§äžèšã®Rustã©ã€ãã©ãªããã±ãŒãžããã«ãããŠããŸããïŒãã®ãªã³ã¯ã¯ãOS XãŠãŒã¶ãŒã«åœ¹ç«ã€å ŽåããããŸãïŒã
cargo build --release
ã¢ã»ã³ããªãçµäºããããçµæã®ã©ã€ãã©ãªã®ååãå€æŽããPythonã¢ãžã¥ãŒã«ãé 眮ãããŠãããã£ã¬ã¯ããªã«ã³ããŒããŠãã¹ã¯ãªããããã€ã³ããŒãã§ããããã«ããŸããCargoã§äœæããã©ã€ãã©ãªã®åå
librust_entropy_lib.so
ã¯ã§ããrust_entropy_lib.so
ããããã®ãã¹ãã®äžéšãšããŠæ£åžžã«ã€ã³ããŒãã§ããããã«ããã«ã¯ãã©ã€ãã©ãªã®ååãã«å€æŽããå¿
èŠããããŸãã
ããã©ãŒãã³ã¹ãã§ãã¯ïŒçµæ
100äžãè¶ ããã©ã³ãã ãã€ãã®ãšã³ããããŒãèšç®ããpytestãã¬ãŒã¯ãã€ã³ãã䜿çšããŠãåé¢æ°å®è£ ã®ããã©ãŒãã³ã¹ã枬å®ããŸããããã¹ãŠã®å®è£ ã¯åãããŒã¿ã§ç€ºãããŠããŸãããã³ãããŒã¯ïŒentropy.pyã«ãå«ãŸããŠããŸãïŒã以äžã«ç€ºããŸãã
# ### ###
# w/ NumPy
NUM = 1000000
VAL = np.random.randint(0, 256, size=(NUM, ), dtype=np.uint8)
def test_pure_python(benchmark):
""" Python."""
benchmark(compute_entropy_pure_python, VAL)
def test_python_scipy_numpy(benchmark):
""" Python SciPy."""
benchmark(compute_entropy_scipy_numpy, VAL)
def test_rust(benchmark):
""" Rust, Python."""
benchmark(compute_entropy_rust_from_python, VAL)
æåŸã«ããšã³ããããŒã®èšç®ã«å¿ èŠãªã¡ãœããããšã«ãåå¥ã®åçŽãªãã©ã€ããŒã¹ã¯ãªãããäœæããŸãã次ã¯ãçŽç²ãªPythonå®è£ ããã¹ãããããã®ä»£è¡šçãªãã©ã€ããŒã¹ã¯ãªããã§ãããã¡ã€ã«ã«ã¯ã
testdata.bin
ãã¹ãŠã®ã¡ãœããããã¹ãããããã«äœ¿çšããã1,000,000ã®ã©ã³ãã ãã€ããå«ãŸããŠããŸããããããã®æ¹æ³ã¯ãèšç®ã100åç¹°ãè¿ããã¡ã¢ãªäœ¿çšéããŒã¿ã®ååŸã容æã«ããŸãã
import entropy
with open('testdata.bin', 'rb') as f:
DATA = f.read()
for _ in range(100):
entropy.compute_entropy_pure_python(DATA)
SciPy / NumPyãšRustã®äž¡æ¹ã®å®è£ ã¯åªããããã©ãŒãã³ã¹ã瀺ããæé©åãããŠããªãçŽç²ãªPythonå®è£ ã100å以äžç°¡åã«ç Žã£ãŠããŸãã RustããŒãžã§ã³ã¯SciPy / NumPyããŒãžã§ã³ããããããã«åªããæ§èœããçºæ®ããŸããã§ããããçµæã¯ç§ãã¡ã®æåŸ ãè£ä»ããŸãããçŽç²ãªPythonã¯ã³ã³ãã€ã«æžã¿èšèªãããã¯ããã«é ããRustã§èšè¿°ãããæ¡åŒµæ©èœã¯Cèšèªã®å¯Ÿå¿ç©ãšéåžžã«ããŸã競åã§ããŸãïŒãã®ãããªå Žåã§ãããããæã¡è² ãããŸãïŒãã€ã¯ããã¹ãïŒã
çç£æ§ãåäžãããæ¹æ³ã¯ä»ã«ããããŸããã¢ãžã¥ãŒã«
ctypes
ãŸãã¯ã䜿çšã§ããŸãcffi
ãã¿ã€ããã³ããè¿œå ããCythonã䜿çšããŠãPythonããã€ã³ããŒãã§ããã©ã€ãã©ãªãçæã§ããŸãããããã®ãªãã·ã§ã³ã¯ãã¹ãŠããœãªã¥ãŒã·ã§ã³åºæã®ãã¬ãŒããªããæ€èšããå¿
èŠããããŸãã
ãŸããGNUã¢ããªã±ãŒã·ã§ã³ã䜿çšããŠãåæ©èœå®è£ ã®ã¡ã¢ãªäœ¿çšéã枬å®ããŸãã
time
ïŒçµã¿èŸŒã¿ã®ã·ã§ã«ã³ãã³ããšæ··åããªãã§ãã ããtime
ïŒãç¹ã«ãåžžé§ã»ããã®æ倧ãµã€ãºã枬å®ããŸããã
çŽç²ãªPythonãšRustã®å®è£ ã§ã¯ããã®éšåã®æ倧ãµã€ãºã¯éåžžã«äŒŒãŠããŸãããSciPy / NumPyã®å®è£ ã§ã¯ããã®ãã³ãããŒã¯ã®ã¡ã¢ãªãå€§å¹ ã«æ¶è²»ãããŸããããã¯ãããããã€ã³ããŒãäžã«ã¡ã¢ãªã«èªã¿èŸŒãŸããè¿œå æ©èœãåå ã§ãããšããããPythonããRustã³ãŒããåŒã³åºããŠããã¡ã¢ãªãªãŒããŒããããå€§å¹ ã«å¢å ããããšã¯ãªãããã§ãã
æŠèŠ
PythonããRustãåŒã³åºããšãã«åŸãããããã©ãŒãã³ã¹ã«éåžžã«æéãåããŸãããç§ãã¡ã®ççŽãªç°¡åãªè©äŸ¡ã§ã¯ãRustã®å®è£ ã¯ãSciPyããã³NumPyããã±ãŒãžã®ããŒã¹Cã®å®è£ ãšããã©ãŒãã³ã¹ã競ãããšãã§ããŸãããéã¯å¹ççãªå€§èŠæš¡åŠçã«æé©ã®ããã§ãã
Rustã¯åªããå®è¡æéã瀺ããã ãã§ã¯ãããŸããããããã®ãã¹ãã®ã¡ã¢ãªãªãŒããŒããããæå°éã§ããããšã«æ³šæããŠãã ããããããã®å®è¡æããã³ã¡ã¢ãªäœ¿çšã®ç¹æ§ã¯ãã¹ã±ãŒã©ããªãã£ã®ç®çã«çæ³çã§ãããšæãããŸãã SciPyãšNumPyã®C FFIå®è£ ã®ããã©ãŒãã³ã¹ã¯ç¢ºãã«åçã§ãããRustã䜿çšãããšãCãšC ++ã§ã¯åŸãããªãè¿œå ã®å©ç¹ãåŸãããŸããã¡ã¢ãªã®å®å šæ§ãšã¹ã¬ããã®å®å šæ§ã®ä¿èšŒã¯éåžžã«é åçãªå©ç¹ã§ãã
Cã¯Rustã«çžåœããã©ã³ã¿ã€ã ãæäŸããŸãããCèªäœã¯ã¹ã¬ããã»ãŒããæäŸããŸããã Cã«ãã®æ©èœãæäŸããå€éšã©ã€ãã©ãªããããŸãããããããæ£ãã䜿çšãããŠããããšã確èªããã®ã¯éçºè ã®è²¬ä»»ã§ãã Rustã¯ãæææš©ã¢ãã«ã®ãããã§ãã³ã³ãã€ã«æã«ã¬ãŒã¹ãªã©ã®ã¹ã¬ããã»ãŒããã£ã®åé¡ãç£èŠããæšæºã©ã€ãã©ãªã¯ããã€ããããã¯ãåç §ã«ãŠã³ããããã¹ããŒããã€ã³ã¿ãªã©ã®åæå®è¡ã¡ã«ããºã ã®ã¹ã€ãŒããæäŸããŸãã
SciPyãNumPyãRustã«ç§»æ€ããããšã¯æšå¥šããŠããŸããããããã®Pythonã©ã€ãã©ãªã¯ãã§ã«æé©åãããŠãããã¯ãŒã«ãªéçºè ã³ãã¥ããã£ã«ãã£ãŠãµããŒããããŠããŸããäžæ¹ãé«æ§èœã©ã€ãã©ãªã§æäŸãããŠããªãã³ãŒããçŽç²ãªPythonããRustã«ç§»æ€ããããšã匷ããå§ãããŸããã»ãã¥ãªãã£åæã«äœ¿çšãããããŒã¿ãµã€ãšã³ã¹ã¢ããªã±ãŒã·ã§ã³ã®ã³ã³ããã¹ãã§ã¯ãRustã¯ããã®é床ãšã»ãã¥ãªãã£ãä¿èšŒãããŠãããããPythonã®ç«¶äºåã®ãã代æ¿æ段ã®ããã§ãã