mirror of
https://git.pumpin.online/funkpower/catena.git
synced 2026-10-22 18:57:14 +00:00
bindings: let go of the interpreter while reading a book
read_colophon is several milliseconds of computation over a few hundred kilobytes, and it held the GIL for all of them. A caller reading a library through asyncio.to_thread therefore got no overlap whatsoever: six books in flight, one book's worth of work at a time. Measured on this library, that was most of why a concurrent pass still paced at four and a half hours.
This commit is contained in:
@@ -451,15 +451,22 @@ fn _catena(module: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
#[pyo3(signature = (text, pages = colophon::PAGES, shelf = None))]
|
||||
fn read_colophon<'py>(
|
||||
py: Python<'py>,
|
||||
text: &str,
|
||||
text: String,
|
||||
pages: usize,
|
||||
shelf: Option<&str>,
|
||||
shelf: Option<String>,
|
||||
) -> PyResult<Bound<'py, PyAny>> {
|
||||
if pages == 0 {
|
||||
return Err(PyValueError::new_err("pages = 0 would read nothing"));
|
||||
}
|
||||
let shelf = shelf.map(colophon::shelf::Shelf::parse);
|
||||
to_py(py, &colophon::read_onto(text, pages, shelf.as_ref()))
|
||||
// Reading a book's front matter is several milliseconds of pure
|
||||
// computation on a few hundred kilobytes, and holding the interpreter for
|
||||
// it makes `asyncio.to_thread` a lie: a caller reading a library several
|
||||
// books at a time got no overlap at all until this let go.
|
||||
let printed = py.detach(move || {
|
||||
let shelf = shelf.as_deref().map(colophon::shelf::Shelf::parse);
|
||||
colophon::read_onto(&text, pages, shelf.as_ref())
|
||||
});
|
||||
to_py(py, &printed)
|
||||
}
|
||||
|
||||
/// File subject headings onto a shelf without reading a book.
|
||||
|
||||
Reference in New Issue
Block a user