Skip to content

int.__sizeof__ from #1426 - #1541

Merged
coolreader18 merged 4 commits into
RustPython:masterfrom
ashermancinelli:int-sizeof
Oct 17, 2019
Merged

coolreader18 merged 4 commits into
RustPython:masterfrom
ashermancinelli:int-sizeof

Conversation

@ashermancinelli

@ashermancinelli ashermancinelli commented Oct 15, 2019 •

Copy link
Copy Markdown
Contributor

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

Comment thread vm/src/obj/objint.rs Outdated

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

ghost Oct 15, 2019 •

Copy link
Copy Markdown
Contributor Author

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

Comment thread vm/src/obj/objint.rs Outdated
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
(self.value.bits() as f64 / 8.).ceil() as usize
mem::size_of::<Self>() as usize

ghost Oct 15, 2019 •

Copy link
Copy Markdown
Contributor Author

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

ghost commented Oct 15, 2019

Copy link
Copy Markdown
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

ghost commented Oct 15, 2019

Copy link
Copy Markdown
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

ghost commented Oct 15, 2019

Copy link
Copy Markdown
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.

Comment thread vm/src/obj/objint.rs Outdated
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
mem::size_of::<Self>() as usize
self.value.bits() + 7 & !7

ghost Oct 15, 2019

Copy link
Copy Markdown
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

ghost Oct 15, 2019

Copy link
Copy Markdown
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

ghost Oct 16, 2019

Copy link
Copy Markdown
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

Comment thread vm/src/obj/objint.rs Outdated
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
self.value.bits() + 7 & !7
mem::size_of::<Self>() + (self.value.bits() + 7) & !7

ghost Oct 16, 2019 •

Copy link
Copy Markdown
Contributor Author

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

ghost Oct 16, 2019

Copy link
Copy Markdown
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

Comment thread vm/src/obj/objint.rs Outdated
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
size_of::<Self>()
(size_of::<Self>() + (self.value.bits() + 7) & !7) / 8

ghost Oct 16, 2019

Copy link
Copy Markdown
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.

ghost Oct 16, 2019

Copy link
Copy Markdown
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.

Comment thread vm/src/obj/objint.rs Resolved
Asher Mancinelli and others added 2 commits October 16, 2019 21:16
Co-Authored-By: Noah <33094578+coolreader18@users.noreply.github.com>

ghost left a comment

Copy link
Copy Markdown
Member

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