Я был очень заинтересован в Apache Arrow в течение некоторого времени из-за обещаний «нулевое копирование чтения», «нулевое значение serde» и «отсутствие накладных расходов для межсистемной связи». Я понимаю проект (через призму pyarrow): он описывает память и формат данных, так что несколько задач могут читать это как карту сокровищ и все найти свой путь к одним и тем же данным (без копирования). Думаю, я могу увидеть, как это работает в Python / Pandas в одном процессе; довольно легко создать массив Arrow, передать его разным объектам и наблюдать за всем «нулевым копированием» в действии.
Однако, когда мы говорим о межсистемной коммуникации без накладных расходов, я почти полностью теряюсь. Например, как PySpark преобразовывает объекты Java в формат стрелки, а затем передает его в Python / Pandas? Я попытался посмотреть код здесь, но для парня, не использующего java / scala, это выглядит так, будто он преобразует искровые строки в объекты Arrow, а затем в byteArray
s (строка 124), что не кажется мне нулевой копией, нулевыми накладными расходами.
Точно так же, если бы я хотел попытаться передать массив Arrow из Python / pyarrow, скажем, в Rust (используя Rust Arrow API), я не мог бы осознать, как бы я это сделал, особенно учитывая, что этот подход к вызову функции Rust из Python не соответствует Кажется, не работает с примитивами Arrow. Есть ли способ указать как Rust, так и Python на один и тот же адрес (а) памяти? Должен ли я каким-то образом отправлять данные стрелок в виде byteArray?
// lib.rs
#[macro_use]
extern crate cpython;
use cpython::{PyResult, Python};
use arrow::array::Int64Array;
use arrow::compute::array_ops::sum;
fn sum_col(_py: Python, val: Int64Array) -> PyResult<i64> {
let total = sum(val).unwrap();
Ok(total)
}
py_module_initializer!(rust_arrow_2, initrust_arrow_2, Pyinit_rust_arrow_2, |py, m| {
m.add(py, "__doc__", "This module is implemented in Rust.")?;
m.add(py, "sum_col", py_fn!(py, sum_col(val: Int64Array)))?;
Ok(())
});
$ cargo build --release
...
error[E0277]: the trait bound `arrow::array::array::PrimitiveArray<arrow::datatypes::Int64Type>: cpython::FromPyObject<'_>` is not satisfied
--> src/lib.rs:15:26
|
15 | m.add(py, "sum_col", py_fn!(py, sum_col(val: Int64Array)))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `cpython::FromPyObject<'_>` is not implemented for `arrow::array::array::PrimitiveArray<arrow::datatypes::Int64Type>`
|
= note: required by `cpython::FromPyObject::extract`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)