-
Notifications
You must be signed in to change notification settings - Fork 784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement 128bit integer conversion for limited API #1310
Conversation
Why use |
This is the snippet I tested:
Or do you think this is slower due to conversion of the arguments from Rust? Hm, you need to construct a whole dictionary for the Of course, both are missing the |
Alternative, as I said in #1309, is to use |
Thanks, I just failed to come up with it. We can call
I tried that first but I found it too complex, especially for |
So in my tests (FromPyObject only) it was slightly faster to call with |
09423d0
to
7f814f7
Compare
@@ -183,11 +173,12 @@ mod int128_conversion { | |||
impl IntoPy<PyObject> for $rust_type { | |||
fn into_py(self, py: Python) -> PyObject { | |||
unsafe { | |||
let bytes = self.to_ne_bytes(); | |||
// Always use little endian | |||
let bytes = self.to_le_bytes(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though it's not related to this PR, I noticed that to_le_bytes
is added in Rust 1.32.
Using always little-endian simplified the code a lot.
let obj = ffi::_PyLong_FromByteArray( | ||
bytes.as_ptr() as *const c_uchar, | ||
$byte_size, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why 16
is not hard-coded...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe bytes.len()
is most correct? I would think that the compiler will still optimize this at compile time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
I think it's better to use std::mem::size_of{_val}
instead of hard-coding 16, as it's easier to understand what that means for a future reader rather than just seeing a magic number 16.
let obj = ffi::_PyLong_FromByteArray( | ||
bytes.as_ptr() as *const c_uchar, | ||
$byte_size, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe bytes.len()
is most correct? I would think that the compiler will still optimize this at compile time.
src/types/num.rs
Outdated
@@ -202,83 +193,131 @@ mod int128_conversion { | |||
if num.is_null() { | |||
return Err(PyErr::fetch(ob.py())); | |||
} | |||
let mut buffer = [0; $byte_size]; | |||
let mut buffer = [0; 16]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let mut buffer = [0; 16]; | |
let mut buffer = [0; std::mem::size_of::<$rust_type>()]; |
src/types/num.rs
Outdated
let ok = ffi::_PyLong_AsByteArray( | ||
num as *mut ffi::PyLongObject, | ||
buffer.as_mut_ptr(), | ||
$byte_size, | ||
IS_LITTLE_ENDIAN, | ||
16, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
16, | |
buffer.len(), |
src/types/num.rs
Outdated
let num = unsafe { ffi::PyNumber_Index(ob.as_ptr()) }; | ||
let num: &PyLong = | ||
unsafe { crate::FromPyPointer::from_owned_ptr_or_err(py, num)? }; | ||
let args = (16, "little".to_object(py)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let args = (16, "little".to_object(py)); | |
let args = (std::mem::size_of::<$rust_type>(), "little".to_object(py)); |
or could define a const SIZE: usize = std::mem::size_of::<$rust_type>()
and use here and on line 258.
7f814f7
to
0cafe3d
Compare
src/types/num.rs
Outdated
ffi::PyNumber_Index(ob.as_ptr()), | ||
) | ||
}?; | ||
let kwargs = [("signed", $is_signed)].into_py_dict(py); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah damn, it requires a dict here too then. Can you at least make this
let kwargs = if $is_signed { Some(...) } else { None };
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure,
0cafe3d
to
8c4cba2
Compare
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
Thank you for your reviews! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
Fix #1309
They would be slow since they use
eval
... but could there be any alternative?