Skip to content

int.__sizeof__ from #1426 #1541

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

Merged
merged 4 commits into from
Oct 17, 2019
Merged

Conversation

ashermancinelli
Copy link
Contributor

@ashermancinelli ashermancinelli commented Oct 15, 2019

Impl from @RobertBerglund 's comment, working on #304

@@ -186,6 +186,11 @@ impl PyInt {
PyInt::new(options.get_int_value(vm)?).into_ref_with_type(vm, cls)
}

#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
(self.value.bits() as f64 / 8.).ceil() as usize
Copy link
Contributor Author

@ashermancinelli ashermancinelli Oct 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Results in:

>>>>> (2**1).__sizeof__()
1
>>>>> (2**8).__sizeof__()
2
>>>>> (2**16).__sizeof__()
3
>>>>> (2**32).__sizeof__()
5
>>>>> (2**64).__sizeof__()
9

Edit: tested better values @coolreader18

@@ -188,7 +189,7 @@ impl PyInt {

#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
(self.value.bits() as f64 / 8.).ceil() as usize
mem::size_of::<Self>() as usize
Copy link
Contributor Author

@ashermancinelli ashermancinelli Oct 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Results in:

>>>>> for i in range(0, 100, 10):
..... 	print((i).__sizeof__())
..... 
32
32
32
.
.
.
32
32

@ashermancinelli
Copy link
Contributor Author

@coolreader18

mem::size_of::<Self>() as usize

This'll just always return 32 I believe, I'm not sure how useful this is. You're right that it goes deeper than I thought 😅

@coolreader18
Copy link
Member

Yeah, it's not as simple as mem::size_of::<T>() because that just returns the size of T on the stack, which is not always necessarily a meaningful value. This thread from the rust forums might be useful; I'm not sure if there was some sort of bug with the f64 conversion.

@coolreader18
Copy link
Member

Although I don't think there was, it just didn't go above 1 byte because 100 can be contained with just 8 binary digits; you'd have to go above 256 to see a change.

@@ -189,7 +188,7 @@ impl PyInt {

#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
mem::size_of::<Self>() as usize
self.value.bits() + 7 & !7
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

>>>>> (2**1).__sizeof__()
8
>>>>> (2**8).__sizeof__()
16
>>>>> (2**16).__sizeof__()
24
>>>>> (2**32).__sizeof__()
40

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coolreader18 I think you're right about just not going high enough, I'll test that out

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sizeof int is sum of size of int object itself + sum of its heap allocated memory.
So, roughly, mem::sizeof<T> + 4 * self.value.data.len() is expected.
If current code describes the latter, adding mem::sizeof will make the value correct

@@ -188,7 +189,7 @@ impl PyInt {

#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
self.value.bits() + 7 & !7
mem::size_of::<Self>() + (self.value.bits() + 7) & !7
Copy link
Contributor Author

@ashermancinelli ashermancinelli Oct 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be 32 bits on the stack + bits on the heap rounded up to the nearest 8 bits.

>>>>> (2**2).__sizeof__()
40
>>>>> (2**8).__sizeof__()
48
>>>>> (2**16).__sizeof__()
56
>>>>> (2**32).__sizeof__()
72

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__sizeof__ should actually return bytes, so you'd probably want to divide the bits you get by 8

@@ -576,7 +576,7 @@ impl PyInt {

#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
size_of::<Self>()
(size_of::<Self>() + (self.value.bits() + 7) & !7) / 8
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Divided by 8 to return bytes instead of bits.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mem::size_of actually does return bytes, it's the BigInt::bits method that returns bits.

ashermancinelli and others added 2 commits October 16, 2019 21:16
Co-Authored-By: Noah <33094578+coolreader18@users.noreply.github.com>
Copy link
Member

@coolreader18 coolreader18 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for working on this!

@coolreader18 coolreader18 merged commit 7980b78 into RustPython:master Oct 17, 2019
@ashermancinelli ashermancinelli deleted the int-sizeof branch October 17, 2019 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants