11use polars:: frame:: row:: { Row , rows_to_schema_supertypes, rows_to_supertypes} ;
22use polars:: prelude:: * ;
33use pyo3:: prelude:: * ;
4- use pyo3:: types:: { PyDict , PyMapping } ;
4+ use pyo3:: types:: { PyDict , PyMapping , PyString } ;
55
66use super :: PyDataFrame ;
77use 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