Skip to content

Commit db27f40

Browse files
optimise use of get_item for PyDict objects
1 parent e09f0ad commit db27f40

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

crates/polars-python/src/dataframe/construction.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use polars::frame::row::{Row, rows_to_schema_supertypes, rows_to_supertypes};
22
use polars::prelude::*;
33
use pyo3::prelude::*;
4-
use pyo3::types::{PyDict, PyMapping};
4+
use pyo3::types::{PyDict, PyMapping, PyString};
55

66
use super::PyDataFrame;
77
use crate::conversion::any_value::py_object_to_any_value;
@@ -166,17 +166,21 @@ fn dicts_to_rows<'a>(
166166
names: &'a [String],
167167
strict: bool,
168168
) -> PyResult<Vec<Row<'a>>> {
169+
let py = data.py();
169170
let mut rows = Vec::with_capacity(data.len()?);
170171
let null_row = Row::new(vec![AnyValue::Null; names.len()]);
171172

173+
// pre-convert keys/names so we don't repeatedly allocate string keys
174+
let py_keys: Vec<Py<PyString>> = names.iter().map(|k| PyString::new(py, k).into()).collect();
175+
172176
for d in data.try_iter()? {
173177
let d = d?;
174178
if d.is_none() {
175179
rows.push(null_row.clone())
176180
} else {
177181
let d = d.downcast::<PyDict>()?;
178182
let mut row = Vec::with_capacity(names.len());
179-
for k in names.iter() {
183+
for k in &py_keys {
180184
let val = match d.get_item(k)? {
181185
None => AnyValue::Null,
182186
Some(val) => py_object_to_any_value(&val.as_borrowed(), strict, true)?,
@@ -194,22 +198,26 @@ fn mappings_to_rows<'a>(
194198
names: &'a [String],
195199
strict: bool,
196200
) -> PyResult<Vec<Row<'a>>> {
201+
let py = data.py();
197202
let mut rows = Vec::with_capacity(data.len()?);
198203
let null_row = Row::new(vec![AnyValue::Null; names.len()]);
199204

205+
// pre-convert keys/names so we don't repeatedly allocate string keys
206+
let py_keys: Vec<Py<PyString>> = names.iter().map(|k| PyString::new(py, k).into()).collect();
207+
200208
for d in data.try_iter()? {
201209
let d = d?;
202210
if d.is_none() {
203211
rows.push(null_row.clone())
204212
} else {
205213
let d = d.downcast::<PyMapping>()?;
206214
let mut row = Vec::with_capacity(names.len());
207-
for k in names.iter() {
208-
let py_obj = d.get_item(k)?;
209-
let val = if py_obj.is_none() {
215+
for k in &py_keys {
216+
let py_val = d.get_item(k)?;
217+
let val = if py_val.is_none() {
210218
AnyValue::Null
211219
} else {
212-
py_object_to_any_value(&py_obj, strict, true)?
220+
py_object_to_any_value(&py_val, strict, true)?
213221
};
214222
row.push(val)
215223
}

0 commit comments

Comments
 (0)