Skip to content

Commit 1a06530

Browse files
committed
Misc readability, performance
1 parent ea43694 commit 1a06530

7 files changed

Lines changed: 57 additions & 98 deletions

File tree

develop

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
rm -f target/wheels/*
44

5-
maturin build --no-sdist --manylinux 2014 -i python3 --release "$@"
5+
maturin build --no-sdist --manylinux off -i python3 --release "$@"
66

77
pip install --force $(find target/wheels -name "*cp3*")

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ pub unsafe extern "C" fn dumps(
271271
let mut default: Option<NonNull<PyObject>> = None;
272272
let mut optsptr: Option<NonNull<PyObject>> = None;
273273

274+
let obj = PyTuple_GET_ITEM(args, 0);
275+
274276
let num_args = PyTuple_GET_SIZE(args);
275277
if unlikely!(num_args == 0) {
276278
return raise_dumps_exception(Cow::Borrowed(
@@ -326,7 +328,7 @@ pub unsafe extern "C" fn dumps(
326328
}
327329
}
328330

329-
match crate::serialize::serialize(PyTuple_GET_ITEM(args, 0), default, optsbits as opt::Opt) {
331+
match crate::serialize::serialize(obj, default, optsbits as opt::Opt) {
330332
Ok(val) => val.as_ptr(),
331333
Err(err) => raise_dumps_exception(Cow::Owned(err)),
332334
}

src/serialize/dataclass.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ impl<'p> Serialize for DataclassFastSerializer {
6262
std::ptr::null_mut(),
6363
)
6464
};
65+
let value = PyObjectSerializer::new(
66+
value,
67+
self.opts,
68+
self.default_calls,
69+
self.recursion + 1,
70+
self.default,
71+
);
6572
if unlikely!(unsafe { ob_type!(key) != STR_TYPE }) {
6673
err!(KEY_MUST_BE_STR)
6774
}
@@ -77,13 +84,7 @@ impl<'p> Serialize for DataclassFastSerializer {
7784
map.serialize_key(key_as_str).unwrap();
7885
}
7986

80-
map.serialize_value(&PyObjectSerializer::new(
81-
value,
82-
self.opts,
83-
self.default_calls,
84-
self.recursion + 1,
85-
self.default,
86-
))?;
87+
map.serialize_value(&value)?;
8788
}
8889
map.end()
8990
}

src/serialize/dict.rs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
22

33
use crate::exc::*;
4+
use crate::ffi::PyDict_GET_SIZE;
45
use crate::opt::*;
56
use crate::serialize::datetime::*;
67
use crate::serialize::serializer::pyobject_to_obtype;
@@ -19,7 +20,6 @@ pub struct Dict {
1920
default_calls: u8,
2021
recursion: u8,
2122
default: Option<NonNull<pyo3::ffi::PyObject>>,
22-
len: usize,
2323
}
2424

2525
impl Dict {
@@ -29,15 +29,13 @@ impl Dict {
2929
default_calls: u8,
3030
recursion: u8,
3131
default: Option<NonNull<pyo3::ffi::PyObject>>,
32-
len: usize,
3332
) -> Self {
3433
Dict {
3534
ptr: ptr,
3635
opts: opts,
3736
default_calls: default_calls,
3837
recursion: recursion,
3938
default: default,
40-
len: len,
4139
}
4240
}
4341
}
@@ -53,7 +51,7 @@ impl<'p> Serialize for Dict {
5351
let mut str_size: pyo3::ffi::Py_ssize_t = 0;
5452
let mut key: *mut pyo3::ffi::PyObject = std::ptr::null_mut();
5553
let mut value: *mut pyo3::ffi::PyObject = std::ptr::null_mut();
56-
for _ in 0..=self.len - 1 {
54+
for _ in 0..=unsafe { PyDict_GET_SIZE(self.ptr) as usize } - 1 {
5755
unsafe {
5856
pyo3::ffi::_PyDict_Next(
5957
self.ptr,
@@ -63,6 +61,13 @@ impl<'p> Serialize for Dict {
6361
std::ptr::null_mut(),
6462
)
6563
};
64+
let value = PyObjectSerializer::new(
65+
value,
66+
self.opts,
67+
self.default_calls,
68+
self.recursion + 1,
69+
self.default,
70+
);
6671
if unlikely!(unsafe { ob_type!(key) != STR_TYPE }) {
6772
err!(KEY_MUST_BE_STR)
6873
}
@@ -74,13 +79,7 @@ impl<'p> Serialize for Dict {
7479
map.serialize_key(str_from_slice!(data, str_size)).unwrap();
7580
}
7681

77-
map.serialize_value(&PyObjectSerializer::new(
78-
value,
79-
self.opts,
80-
self.default_calls,
81-
self.recursion + 1,
82-
self.default,
83-
))?;
82+
map.serialize_value(&value)?;
8483
}
8584
map.end()
8685
}
@@ -92,7 +91,6 @@ pub struct DictSortedKey {
9291
default_calls: u8,
9392
recursion: u8,
9493
default: Option<NonNull<pyo3::ffi::PyObject>>,
95-
len: usize,
9694
}
9795

9896
impl DictSortedKey {
@@ -102,15 +100,13 @@ impl DictSortedKey {
102100
default_calls: u8,
103101
recursion: u8,
104102
default: Option<NonNull<pyo3::ffi::PyObject>>,
105-
len: usize,
106103
) -> Self {
107104
DictSortedKey {
108105
ptr: ptr,
109106
opts: opts,
110107
default_calls: default_calls,
111108
recursion: recursion,
112109
default: default,
113-
len: len,
114110
}
115111
}
116112
}
@@ -121,13 +117,14 @@ impl<'p> Serialize for DictSortedKey {
121117
where
122118
S: Serializer,
123119
{
120+
let len = unsafe { PyDict_GET_SIZE(self.ptr) as usize };
124121
let mut items: SmallVec<[(&str, *mut pyo3::ffi::PyObject); 8]> =
125-
SmallVec::with_capacity(self.len);
122+
SmallVec::with_capacity(len);
126123
let mut pos = 0isize;
127124
let mut str_size: pyo3::ffi::Py_ssize_t = 0;
128125
let mut key: *mut pyo3::ffi::PyObject = std::ptr::null_mut();
129126
let mut value: *mut pyo3::ffi::PyObject = std::ptr::null_mut();
130-
for _ in 0..=self.len - 1 {
127+
for _ in 0..=len - 1 {
131128
unsafe {
132129
pyo3::ffi::_PyDict_Next(
133130
self.ptr,
@@ -180,7 +177,6 @@ pub struct DictNonStrKey {
180177
default_calls: u8,
181178
recursion: u8,
182179
default: Option<NonNull<pyo3::ffi::PyObject>>,
183-
len: usize,
184180
}
185181

186182
impl DictNonStrKey {
@@ -190,15 +186,13 @@ impl DictNonStrKey {
190186
default_calls: u8,
191187
recursion: u8,
192188
default: Option<NonNull<pyo3::ffi::PyObject>>,
193-
len: usize,
194189
) -> Self {
195190
DictNonStrKey {
196191
ptr: ptr,
197192
opts: opts,
198193
default_calls: default_calls,
199194
recursion: recursion,
200195
default: default,
201-
len: len,
202196
}
203197
}
204198

@@ -310,14 +304,15 @@ impl<'p> Serialize for DictNonStrKey {
310304
where
311305
S: Serializer,
312306
{
307+
let len = unsafe { PyDict_GET_SIZE(self.ptr) as usize };
313308
let mut items: SmallVec<[(InlinableString, *mut pyo3::ffi::PyObject); 8]> =
314-
SmallVec::with_capacity(self.len);
309+
SmallVec::with_capacity(len);
315310
let mut pos = 0isize;
316311
let mut str_size: pyo3::ffi::Py_ssize_t = 0;
317312
let mut key: *mut pyo3::ffi::PyObject = std::ptr::null_mut();
318313
let mut value: *mut pyo3::ffi::PyObject = std::ptr::null_mut();
319314
let opts = self.opts & NOT_PASSTHROUGH;
320-
for _ in 0..=self.len - 1 {
315+
for _ in 0..=len - 1 {
321316
unsafe {
322317
pyo3::ffi::_PyDict_Next(
323318
self.ptr,

src/serialize/list.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ pub struct ListSerializer {
1212
default_calls: u8,
1313
recursion: u8,
1414
default: Option<NonNull<pyo3::ffi::PyObject>>,
15-
len: usize,
1615
}
1716

1817
impl ListSerializer {
@@ -22,43 +21,38 @@ impl ListSerializer {
2221
default_calls: u8,
2322
recursion: u8,
2423
default: Option<NonNull<pyo3::ffi::PyObject>>,
25-
len: usize,
2624
) -> Self {
2725
ListSerializer {
2826
ptr: ptr,
2927
opts: opts,
3028
default_calls: default_calls,
3129
recursion: recursion,
3230
default: default,
33-
len: len,
3431
}
3532
}
3633
}
3734

3835
impl<'p> Serialize for ListSerializer {
39-
#[inline(never)]
4036
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
4137
where
4238
S: Serializer,
4339
{
44-
let mut type_ptr = std::ptr::null_mut();
45-
let mut ob_type = ObType::Str;
46-
4740
let mut seq = serializer.serialize_seq(None).unwrap();
48-
for i in 0..=self.len - 1 {
49-
let elem = unsafe { *(*(self.ptr as *mut pyo3::ffi::PyListObject)).ob_item.add(i) };
50-
if ob_type!(elem) != type_ptr {
51-
type_ptr = ob_type!(elem);
52-
ob_type = pyobject_to_obtype(elem, self.opts);
53-
}
54-
seq.serialize_element(&PyObjectSerializer::with_obtype(
55-
elem,
56-
ob_type,
41+
let slice: &[*mut pyo3::ffi::PyObject] = unsafe {
42+
std::slice::from_raw_parts(
43+
(*(self.ptr as *mut pyo3::ffi::PyListObject)).ob_item,
44+
ffi!(PyList_GET_SIZE(self.ptr)) as usize,
45+
)
46+
};
47+
for &each in slice {
48+
let value = PyObjectSerializer::new(
49+
each,
5750
self.opts,
5851
self.default_calls,
5952
self.recursion + 1,
6053
self.default,
61-
))?;
54+
);
55+
seq.serialize_element(&value)?;
6256
}
6357
seq.end()
6458
}

src/serialize/serializer.rs

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,9 @@ pub fn serialize(
2727
opts: Opt,
2828
) -> Result<NonNull<pyo3::ffi::PyObject>, String> {
2929
let mut buf = BytesWriter::new();
30-
let obtype = pyobject_to_obtype(ptr, opts);
31-
match obtype {
32-
ObType::List | ObType::Dict | ObType::Dataclass | ObType::NumpyArray => {
33-
buf.resize(1024);
34-
}
35-
_ => {}
36-
}
37-
buf.prefetch();
38-
let obj = PyObjectSerializer::with_obtype(ptr, obtype, opts, 0, 0, default);
30+
let obj = PyObjectSerializer::new(ptr, opts, 0, 0, default);
3931
let res;
40-
if likely!(opts & INDENT_2 != INDENT_2) {
32+
if opts & INDENT_2 != INDENT_2 {
4133
res = serde_json::to_writer(&mut buf, &obj);
4234
} else {
4335
res = serde_json::to_writer_pretty(&mut buf, &obj);
@@ -78,7 +70,6 @@ pub enum ObType {
7870
Unknown,
7971
}
8072

81-
#[inline]
8273
pub fn pyobject_to_obtype(obj: *mut pyo3::ffi::PyObject, opts: Opt) -> ObType {
8374
unsafe {
8475
let ob_type = ob_type!(obj);
@@ -164,7 +155,6 @@ pub struct PyObjectSerializer {
164155
}
165156

166157
impl PyObjectSerializer {
167-
#[inline]
168158
pub fn new(
169159
ptr: *mut pyo3::ffi::PyObject,
170160
opts: Opt,
@@ -181,25 +171,6 @@ impl PyObjectSerializer {
181171
default: default,
182172
}
183173
}
184-
185-
#[inline]
186-
pub fn with_obtype(
187-
ptr: *mut pyo3::ffi::PyObject,
188-
obtype: ObType,
189-
opts: Opt,
190-
default_calls: u8,
191-
recursion: u8,
192-
default: Option<NonNull<pyo3::ffi::PyObject>>,
193-
) -> Self {
194-
PyObjectSerializer {
195-
ptr: ptr,
196-
obtype: obtype,
197-
opts: opts,
198-
default_calls: default_calls,
199-
recursion: recursion,
200-
default: default,
201-
}
202-
}
203174
}
204175

205176
impl<'p> Serialize for PyObjectSerializer {
@@ -225,8 +196,7 @@ impl<'p> Serialize for PyObjectSerializer {
225196
if unlikely!(self.recursion == RECURSION_LIMIT) {
226197
err!(RECURSION_LIMIT_REACHED)
227198
}
228-
let len = unsafe { PyDict_GET_SIZE(self.ptr) as usize };
229-
if unlikely!(len == 0) {
199+
if unlikely!(unsafe { PyDict_GET_SIZE(self.ptr) as usize } == 0) {
230200
serializer.serialize_map(Some(0)).unwrap().end()
231201
} else if likely!(self.opts & SORT_OR_NON_STR_KEYS == 0) {
232202
Dict::new(
@@ -235,7 +205,6 @@ impl<'p> Serialize for PyObjectSerializer {
235205
self.default_calls,
236206
self.recursion,
237207
self.default,
238-
len,
239208
)
240209
.serialize(serializer)
241210
} else if self.opts & NON_STR_KEYS != 0 {
@@ -245,7 +214,6 @@ impl<'p> Serialize for PyObjectSerializer {
245214
self.default_calls,
246215
self.recursion,
247216
self.default,
248-
len,
249217
)
250218
.serialize(serializer)
251219
} else {
@@ -255,7 +223,6 @@ impl<'p> Serialize for PyObjectSerializer {
255223
self.default_calls,
256224
self.recursion,
257225
self.default,
258-
len,
259226
)
260227
.serialize(serializer)
261228
}
@@ -264,8 +231,7 @@ impl<'p> Serialize for PyObjectSerializer {
264231
if unlikely!(self.recursion == RECURSION_LIMIT) {
265232
err!(RECURSION_LIMIT_REACHED)
266233
}
267-
let len = ffi!(PyList_GET_SIZE(self.ptr)) as usize;
268-
if unlikely!(len == 0) {
234+
if unlikely!(ffi!(PyList_GET_SIZE(self.ptr)) as usize == 0) {
269235
serializer.serialize_seq(Some(0)).unwrap().end()
270236
} else {
271237
ListSerializer::new(
@@ -274,7 +240,6 @@ impl<'p> Serialize for PyObjectSerializer {
274240
self.default_calls,
275241
self.recursion,
276242
self.default,
277-
len,
278243
)
279244
.serialize(serializer)
280245
}

0 commit comments

Comments
 (0)