Skip to content

Commit 8cc74de

Browse files
committed
more optimizations
1 parent 20247b5 commit 8cc74de

File tree

2 files changed

+56
-50
lines changed

2 files changed

+56
-50
lines changed

src/driver/common.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,13 @@ macro_rules! impl_config_py_methods {
7777
#[cfg(not(unix))]
7878
#[getter]
7979
fn hosts(&self) -> Vec<String> {
80-
let mut hosts_vec = vec![];
81-
82-
let hosts = self.pg_config.get_hosts();
83-
for host in hosts {
84-
match host {
85-
Host::Tcp(host) => {
86-
hosts_vec.push(host.to_string());
87-
}
88-
_ => unreachable!(),
89-
}
90-
}
91-
92-
hosts_vec
80+
self.pg_config
81+
.get_hosts()
82+
.iter()
83+
.map(|host| match host {
84+
Host::Tcp(host) => host.to_string(),
85+
})
86+
.collect()
9387
}
9488

9589
#[getter]

src/value_converter/to_python.rs

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,9 @@ fn postgres_array_to_py<'py, T: IntoPyObject<'py> + Clone>(
9595
array: Option<Array<T>>,
9696
) -> Option<Py<PyList>> {
9797
array.map(|array| {
98-
inner_postgres_array_to_py(
99-
py,
100-
array.dimensions(),
101-
array.iter().cloned().collect::<Vec<T>>(),
102-
0,
103-
0,
104-
)
98+
// Collect data once instead of creating copies in recursion
99+
let data: Vec<T> = array.iter().cloned().collect();
100+
inner_postgres_array_to_py(py, array.dimensions(), &data, 0, 0)
105101
})
106102
}
107103

@@ -110,44 +106,60 @@ fn postgres_array_to_py<'py, T: IntoPyObject<'py> + Clone>(
110106
fn inner_postgres_array_to_py<'py, T>(
111107
py: Python<'py>,
112108
dimensions: &[Dimension],
113-
data: Vec<T>,
109+
data: &[T],
114110
dimension_index: usize,
115-
mut lower_bound: usize,
111+
data_offset: usize,
116112
) -> Py<PyList>
117113
where
118114
T: IntoPyObject<'py> + Clone,
119115
{
120-
let current_dimension = dimensions.get(dimension_index);
121-
122-
if let Some(current_dimension) = current_dimension {
123-
let possible_next_dimension = dimensions.get(dimension_index + 1);
124-
match possible_next_dimension {
125-
Some(next_dimension) => {
126-
let final_list = PyList::empty(py);
127-
128-
for _ in 0..current_dimension.len as usize {
129-
if dimensions.get(dimension_index + 1).is_some() {
130-
let inner_pylist = inner_postgres_array_to_py(
131-
py,
132-
dimensions,
133-
data[lower_bound..next_dimension.len as usize + lower_bound].to_vec(),
134-
dimension_index + 1,
135-
0,
136-
);
137-
final_list.append(inner_pylist).unwrap();
138-
lower_bound += next_dimension.len as usize;
139-
}
140-
}
141-
142-
return final_list.unbind();
143-
}
144-
None => {
145-
return PyList::new(py, data).unwrap().unbind(); // TODO unwrap is unsafe
146-
}
116+
// Check bounds early
117+
if dimension_index >= dimensions.len() || data_offset >= data.len() {
118+
return PyList::empty(py).unbind();
119+
}
120+
121+
let current_dimension = &dimensions[dimension_index];
122+
let current_len = current_dimension.len as usize;
123+
124+
// If this is the last dimension, create a list with the actual data
125+
if dimension_index + 1 >= dimensions.len() {
126+
let end_offset = (data_offset + current_len).min(data.len());
127+
let slice = &data[data_offset..end_offset];
128+
129+
// Create Python list more efficiently
130+
return match PyList::new(py, slice.iter().cloned()) {
131+
Ok(list) => list.unbind(),
132+
Err(_) => PyList::empty(py).unbind(),
133+
};
134+
}
135+
136+
// For multi-dimensional arrays, recursively create nested lists
137+
let final_list = PyList::empty(py);
138+
139+
// Calculate the size of each sub-array
140+
let sub_array_size = dimensions[dimension_index + 1..]
141+
.iter()
142+
.map(|d| d.len as usize)
143+
.product::<usize>();
144+
145+
let mut current_offset = data_offset;
146+
147+
for _ in 0..current_len {
148+
if current_offset >= data.len() {
149+
break;
147150
}
151+
152+
let inner_list =
153+
inner_postgres_array_to_py(py, dimensions, data, dimension_index + 1, current_offset);
154+
155+
if final_list.append(inner_list).is_err() {
156+
break;
157+
}
158+
159+
current_offset += sub_array_size;
148160
}
149161

150-
PyList::empty(py).unbind()
162+
final_list.unbind()
151163
}
152164

153165
#[allow(clippy::too_many_lines)]

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy