Ускорение ветвления плагина ржавчины PolarsPython

Программы на Python
Anonymous
 Ускорение ветвления плагина ржавчины Polars

Сообщение Anonymous »

Я следую руководству по плагинам Polars — неправильные прогнозы ветвей, и там говорится, что есть более быстрый способ реализовать следующий код:

Код: Выделить всё

#[polars_expr(output_type=Int64)]
fn sum_i64(inputs: &[Series]) -> PolarsResult {
let left: &Int64Chunked = inputs[0].i64()?;
let right: &Int64Chunked = inputs[1].i64()?;
// Note: there's a faster way of summing two columns, see
// section 7.
let out: Int64Chunked = broadcast_binary_elementwise(
left,
right,
|left: Option, right: Option| match (left, right) {
(Some(left), Some(right)) => Some(left + right),
_ => None,
},
);
Ok(out.into_series())
}
избегая ветвления при проверке того, является ли значение нулевым или нет. Используя предложение @Chayim Friedman о Broadcast_binary_elementwise_values, я смог заставить функцию добавления в Rust соответствовать простому добавлению обоих столбцов в полярах. Однако когда я вместо этого использую умножение, оно теперь работает значительно медленнее, даже медленнее, чем цикл, который выполняет ветвящееся поведение (т. е. скалярное произведение двух столбцов). Ожидается ли это для умножения и есть ли способ ускорить add_sum (сложение всех элементов в обоих столбцах вместе) или mul_sum (точечное произведение).
Я провожу следующие тесты на Python, чтобы сравнить скорости:
код Python

Код: Выделить всё

import polars as pl
import time
import minimal_plugin as mp

FILE = "out.parquet"

def make_df():
B = 1 PolarsResult  {
let left: &Int64Chunked = inputs[0].i64()?;
let right: &Int64Chunked = inputs[1].i64()?;
let mut total = 0i64;
left.iter().zip(right.iter()).for_each(|(v, w)| {
if let (Some(v), Some(w)) = (v, w) {
total += v * w;
}
});
Ok(Series::new(PlSmallStr::EMPTY, vec![total]))
}

вывод

Код: Выделить всё

Number of cols: 67108865
shape: (1, 1)
┌─────────────┐
│ a           │
│ ---         │
│ i64         │
╞═════════════╡
│ 39210752000 │
└─────────────┘
--- 0.3578624725341797 seconds ---
shape: (1, 1)
┌─────────────┐
│ a           │
│ ---         │
│ i64         │
╞═════════════╡
│ 39210752000 │
└─────────────┘
--- 0.32439661026000977 seconds ---
shape: (1, 1)
┌─────────────┐
│ a           │
│ ---         │
│ i64         │
╞═════════════╡
│ 39210752000 │
└─────────────┘
--- 12.178003311157227 seconds ---
shape: (1, 1)
┌────────────────┐
│ a              │
│ ---            │
│ i64            │
╞════════════════╡
│ 11698686354804 │
└────────────────┘
--- 0.5033366680145264 seconds ---
shape: (1, 1)
┌────────────────┐
│ a              │
│ ---            │
│ i64            │
╞════════════════╡
│ 11698686354804 │
└────────────────┘
--- 15.640114068984985 seconds ---
shape: (1, 1)
┌────────────────┐
│ a              │
│ ---            │
│ i64            │
╞════════════════╡
│ 11698686354804 │
└────────────────┘
--- 6.710941314697266 seconds ---
Редактирование 1:
Изменено Broadcast_binary_elementwise на Broadcast_binary_elementwise_values, тестовый кадр данных также включает None и повторил тестовые примеры, но для умножения

Подробнее здесь: https://stackoverflow.com/questions/797 ... -branching

Вернуться в «Python»