Performance is a reason to replace a bottleneck, not a reason to rewrite an entire application. Identify the code that limits execution, move a small part to Rust, and keep the surrounding application working. Consider memory safety and maintainability alongside speed. section 1.10 section 8.6
A faster implementation is useful only if it fits the application. Rust’s type system defines data contracts, ownership clarifies responsibility for shared memory across foreign-function boundaries, and thread-safety guarantees support parallel work. Plan how to deploy the replacement without disrupting users. section 1.3 section 1.6
A Python bottleneck
Consider a Python function that generates a Mandelbrot image. Moving the computation into a Rust function callable through PyO3 preserves a Python entry point. A further change uses `py.allow_threads` around that function so other threads can run; Python’s thread pool alone had not substantially improved overall execution time because of the GIL. section 8.6
Listing 8.11 lib.rs: Adding a thread-safe function
#[pyfunction]
fn mandelbrot_fast(
py: Python<'_>,
size: u32,
path: &str,
range_x0: f64,
range_y0: f64,
range_x1: f64,
range_y1: f64,
) {
py.allow_threads(|| mandelbrot_func(size, path, range_x0, range_y0,
range_x1, range_y1)) #1
}
#[pymodule]
fn mandelbrot(_py: Python, m: &PyModule) -> PyResult<()> {
...
m.add_function(wrap_pyfunction!(mandelbrot_fast, m)?)?;
Ok(())
}
Compare the Rust wrapper with the initial function: the wrapper releases the GIL while the image computation runs. section 8.6
The same decision applies in a browser: Rust compiled to WebAssembly is an option when JavaScript code needs better speed or safety. Benchmark changes rather than assuming a speedup; Criterion is named as a tool for benchmarking Rust code. section 9.2 section 6.0







































