A new version of System was added to project The Inbox: http://source.squeak.org/inbox/System-mt.1175.mcz
==================== Summary ====================
Name: System-mt.1175 Author: mt Time: 29 September 2020, 1:16:45.233157 pm UUID: f0acc060-a48b-2c4f-8b56-aaf2f55601b4 Ancestors: System-topa.1174
Adds a way to compute a space tally for objects up to a certain depth.
Questions: - Is the interface (i.e. "depth" and "seen") OK? - Is the use of IdentitySet OK? - Can we speed this up somehow? - Do we need depth-messages for the "class analysis" protocol, too?
=============== Diff against System-topa.1174 ===============
Item was added: + ----- Method: SpaceTally>>spaceForInstance:depth: (in category 'instance size') ----- + spaceForInstance: anObject depth: anInteger + + ^ self spaceForInstance: anObject depth: anInteger seen: IdentitySet new!
Item was added: + ----- Method: SpaceTally>>spaceForInstance:depth:seen: (in category 'instance size') ----- + spaceForInstance: anObject depth: anInteger seen: someObjects + + | class depth total | + (someObjects includes: anObject) ifTrue: [^ 0]. + someObjects add: anObject. + class := anObject class. + depth := anInteger - 1. + total := class isVariable + ifTrue: [class byteSizeOfInstanceOfSize: anObject basicSize] + ifFalse: [class isImmediateClass ifTrue: [0] ifFalse: [class byteSizeOfInstance]]. + depth >= 0 ifTrue: [ + anObject isCompiledCode + ifTrue: [ + anObject literalsDo: [:literal | + total := total + (self spaceForInstance: literal depth: depth seen: someObjects)]] + ifFalse: [ + 1 to: anObject basicSize do: [:index | + total := total + (self spaceForInstance: (anObject basicAt: index) depth: depth seen: someObjects)]. + 1 to: class instSize do: [:index | + total := total + (self spaceForInstance: (anObject instVarAt: index) depth: depth seen: someObjects)]]]. + ^ total!
Item was added: + ----- Method: SpaceTally>>spaceForInstancesOf:depth: (in category 'instance size') ----- + spaceForInstancesOf: aClass depth: aNumber + "Answer a pair of the number of bytes consumed by all instances of the given class, including their object headers, and the number of instances. Follow each instance's fields up to the given depth. Beware of cycles to shared objects, which will tamper the resulting numbers. + + SpaceTally new spaceForInstancesOf: Form depth: 0. --- Same as #spaceForInstanecsOf: + SpaceTally new spaceForInstancesOf: Form depth: 1. --- Includes memory footprint for bits etc. + SpaceTally new spaceForInstancesOf: Form depth: 2. --- Also includes LargePositiveIntegers in bitmaps ;-) + " + + | instances total sub depth | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. + total := 0. + instances do: [:each | total := total + (self spaceForInstance: each depth: aNumber)]. + ^{ total. instances size }!
... we may want to add #spaceUsed on Object, too, and refine it for, e.g., Form to use depth = 2. Those depth values depend on the particular object/class design. Yet, being able to call "myMorph spaceUsed" or "myForm spaceUsed" could be a great debugging tool.
Best, Marcel Am 29.09.2020 13:16:58 schrieb commits@source.squeak.org commits@source.squeak.org: A new version of System was added to project The Inbox: http://source.squeak.org/inbox/System-mt.1175.mcz
==================== Summary ====================
Name: System-mt.1175 Author: mt Time: 29 September 2020, 1:16:45.233157 pm UUID: f0acc060-a48b-2c4f-8b56-aaf2f55601b4 Ancestors: System-topa.1174
Adds a way to compute a space tally for objects up to a certain depth.
Questions: - Is the interface (i.e. "depth" and "seen") OK? - Is the use of IdentitySet OK? - Can we speed this up somehow? - Do we need depth-messages for the "class analysis" protocol, too?
=============== Diff against System-topa.1174 ===============
Item was added: + ----- Method: SpaceTally>>spaceForInstance:depth: (in category 'instance size') ----- + spaceForInstance: anObject depth: anInteger + + ^ self spaceForInstance: anObject depth: anInteger seen: IdentitySet new!
Item was added: + ----- Method: SpaceTally>>spaceForInstance:depth:seen: (in category 'instance size') ----- + spaceForInstance: anObject depth: anInteger seen: someObjects + + | class depth total | + (someObjects includes: anObject) ifTrue: [^ 0]. + someObjects add: anObject. + class := anObject class. + depth := anInteger - 1. + total := class isVariable + ifTrue: [class byteSizeOfInstanceOfSize: anObject basicSize] + ifFalse: [class isImmediateClass ifTrue: [0] ifFalse: [class byteSizeOfInstance]]. + depth >= 0 ifTrue: [ + anObject isCompiledCode + ifTrue: [ + anObject literalsDo: [:literal | + total := total + (self spaceForInstance: literal depth: depth seen: someObjects)]] + ifFalse: [ + 1 to: anObject basicSize do: [:index | + total := total + (self spaceForInstance: (anObject basicAt: index) depth: depth seen: someObjects)]. + 1 to: class instSize do: [:index | + total := total + (self spaceForInstance: (anObject instVarAt: index) depth: depth seen: someObjects)]]]. + ^ total!
Item was added: + ----- Method: SpaceTally>>spaceForInstancesOf:depth: (in category 'instance size') ----- + spaceForInstancesOf: aClass depth: aNumber + "Answer a pair of the number of bytes consumed by all instances of the given class, including their object headers, and the number of instances. Follow each instance's fields up to the given depth. Beware of cycles to shared objects, which will tamper the resulting numbers. + + SpaceTally new spaceForInstancesOf: Form depth: 0. --- Same as #spaceForInstanecsOf: + SpaceTally new spaceForInstancesOf: Form depth: 1. --- Includes memory footprint for bits etc. + SpaceTally new spaceForInstancesOf: Form depth: 2. --- Also includes LargePositiveIntegers in bitmaps ;-) + " + + | instances total sub depth | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. + total := 0. + instances do: [:each | total := total + (self spaceForInstance: each depth: aNumber)]. + ^{ total. instances size }!
One minor performance tweak would be to employ #ifAbsentAdd: on "someObjects" instead of #includes:, followed by #add:.
On Tue, Sep 29, 2020 at 6:21 AM Marcel Taeumel marcel.taeumel@hpi.de wrote:
... we may want to add #spaceUsed on Object, too, and refine it for, e.g., Form to use depth = 2. Those depth values depend on the particular object/class design. Yet, being able to call "myMorph spaceUsed" or "myForm spaceUsed" could be a great debugging tool.
Best, Marcel
Am 29.09.2020 13:16:58 schrieb commits@source.squeak.org < commits@source.squeak.org>: A new version of System was added to project The Inbox: http://source.squeak.org/inbox/System-mt.1175.mcz
==================== Summary ====================
Name: System-mt.1175 Author: mt Time: 29 September 2020, 1:16:45.233157 pm UUID: f0acc060-a48b-2c4f-8b56-aaf2f55601b4 Ancestors: System-topa.1174
Adds a way to compute a space tally for objects up to a certain depth.
Questions:
- Is the interface (i.e. "depth" and "seen") OK?
- Is the use of IdentitySet OK?
- Can we speed this up somehow?
- Do we need depth-messages for the "class analysis" protocol, too?
=============== Diff against System-topa.1174 ===============
Item was added:
- ----- Method: SpaceTally>>spaceForInstance:depth: (in category 'instance
size') -----
- spaceForInstance: anObject depth: anInteger
- ^ self spaceForInstance: anObject depth: anInteger seen: IdentitySet new!
Item was added:
- ----- Method: SpaceTally>>spaceForInstance:depth:seen: (in category
'instance size') -----
- spaceForInstance: anObject depth: anInteger seen: someObjects
- | class depth total |
- (someObjects includes: anObject) ifTrue: [^ 0].
- someObjects add: anObject.
- class := anObject class.
- depth := anInteger - 1.
- total := class isVariable
- ifTrue: [class byteSizeOfInstanceOfSize: anObject basicSize]
- ifFalse: [class isImmediateClass ifTrue: [0] ifFalse: [class
byteSizeOfInstance]].
- depth >= 0 ifTrue: [
- anObject isCompiledCode
- ifTrue: [
- anObject literalsDo: [:literal |
- total := total + (self spaceForInstance: literal depth: depth seen:
someObjects)]]
- ifFalse: [
- 1 to: anObject basicSize do: [:index |
- total := total + (self spaceForInstance: (anObject basicAt: index)
depth: depth seen: someObjects)].
- 1 to: class instSize do: [:index |
- total := total + (self spaceForInstance: (anObject instVarAt: index)
depth: depth seen: someObjects)]]].
- ^ total!
Item was added:
- ----- Method: SpaceTally>>spaceForInstancesOf:depth: (in category
'instance size') -----
- spaceForInstancesOf: aClass depth: aNumber
- "Answer a pair of the number of bytes consumed by all instances of the
given class, including their object headers, and the number of instances. Follow each instance's fields up to the given depth. Beware of cycles to shared objects, which will tamper the resulting numbers.
- SpaceTally new spaceForInstancesOf: Form depth: 0. --- Same as
#spaceForInstanecsOf:
- SpaceTally new spaceForInstancesOf: Form depth: 1. --- Includes memory
footprint for bits etc.
- SpaceTally new spaceForInstancesOf: Form depth: 2. --- Also includes
LargePositiveIntegers in bitmaps ;-)
- "
- | instances total sub depth |
- instances := aClass allInstances.
- instances isEmpty ifTrue: [^#(0 0)].
- total := 0.
- instances do: [:each | total := total + (self spaceForInstance: each
depth: aNumber)].
- ^{ total. instances size }!
Hi Marcel,
On Tue, 29 Sep 2020, commits@source.squeak.org wrote:
A new version of System was added to project The Inbox: http://source.squeak.org/inbox/System-mt.1175.mcz
==================== Summary ====================
Name: System-mt.1175 Author: mt Time: 29 September 2020, 1:16:45.233157 pm UUID: f0acc060-a48b-2c4f-8b56-aaf2f55601b4 Ancestors: System-topa.1174
Adds a way to compute a space tally for objects up to a certain depth.
Questions:
- Is the interface (i.e. "depth" and "seen") OK?
Yes, except for the variable names. IMHO they should be called depth and seenObjects instead of anInteger and someObjects, respectively.
- Is the use of IdentitySet OK?
Yes, it is, however the set should be shared when you iterate over #allInstances to avoid calculating duplicates.
- Can we speed this up somehow?
Yes. 2x speedup is possible[1] for Forms with depth 2. However, the code only works for Objects, so the first non-Object proxy will halt the code. If you want to make it work for all objects, you'll have to use mirror primitives, which will reduce the speedup to about 1.25x.
- Do we need depth-messages for the "class analysis" protocol, too?
No idea, never really used SpaceTally :)
Levente
[1] I wrote some code using various optimizations. If you want me to, I can upload it to the Inbox with or without mirror primitives.
=============== Diff against System-topa.1174 ===============
Item was added:
- ----- Method: SpaceTally>>spaceForInstance:depth: (in category 'instance size') -----
- spaceForInstance: anObject depth: anInteger
- ^ self spaceForInstance: anObject depth: anInteger seen: IdentitySet new!
Item was added:
- ----- Method: SpaceTally>>spaceForInstance:depth:seen: (in category 'instance size') -----
- spaceForInstance: anObject depth: anInteger seen: someObjects
- | class depth total |
- (someObjects includes: anObject) ifTrue: [^ 0].
- someObjects add: anObject.
- class := anObject class.
- depth := anInteger - 1.
- total := class isVariable
ifTrue: [class byteSizeOfInstanceOfSize: anObject basicSize]
ifFalse: [class isImmediateClass ifTrue: [0] ifFalse: [class byteSizeOfInstance]].
- depth >= 0 ifTrue: [
anObject isCompiledCode
ifTrue: [
anObject literalsDo: [:literal |
total := total + (self spaceForInstance: literal depth: depth seen: someObjects)]]
ifFalse: [
1 to: anObject basicSize do: [:index |
total := total + (self spaceForInstance: (anObject basicAt: index) depth: depth seen: someObjects)].
1 to: class instSize do: [:index |
total := total + (self spaceForInstance: (anObject instVarAt: index) depth: depth seen: someObjects)]]].
- ^ total!
Item was added:
- ----- Method: SpaceTally>>spaceForInstancesOf:depth: (in category 'instance size') -----
- spaceForInstancesOf: aClass depth: aNumber
- "Answer a pair of the number of bytes consumed by all instances of the given class, including their object headers, and the number of instances. Follow each instance's fields up to the given depth. Beware of cycles to shared objects, which will tamper the resulting numbers.
- SpaceTally new spaceForInstancesOf: Form depth: 0. --- Same as #spaceForInstanecsOf:
- SpaceTally new spaceForInstancesOf: Form depth: 1. --- Includes memory footprint for bits etc.
- SpaceTally new spaceForInstancesOf: Form depth: 2. --- Also includes LargePositiveIntegers in bitmaps ;-)
- "
- | instances total sub depth |
- instances := aClass allInstances.
- instances isEmpty ifTrue: [^#(0 0)].
- total := 0.
- instances do: [:each | total := total + (self spaceForInstance: each depth: aNumber)].
- ^{ total. instances size }!
Hi Levente, hi Chris.
Thanks for the suggestions! I put the changes into Trunk.
[1] I wrote some code using various optimizations. If you want me to, I can upload it to the Inbox with or without mirror primitives.
Feel free to further optimize SpaceTally >> #spaceForInstance:depth:seen:. Yes, proxy classes should work, too.
Best, Marcel
Levente Uzonyi wrote
Hi Marcel,
On Tue, 29 Sep 2020,
commits@.squeak
wrote:
A new version of System was added to project The Inbox: http://source.squeak.org/inbox/System-mt.1175.mcz
==================== Summary ====================
Name: System-mt.1175 Author: mt Time: 29 September 2020, 1:16:45.233157 pm UUID: f0acc060-a48b-2c4f-8b56-aaf2f55601b4 Ancestors: System-topa.1174
Adds a way to compute a space tally for objects up to a certain depth.
Questions:
- Is the interface (i.e. "depth" and "seen") OK?
Yes, except for the variable names. IMHO they should be called depth and seenObjects instead of anInteger and someObjects, respectively.
- Is the use of IdentitySet OK?
Yes, it is, however the set should be shared when you iterate over #allInstances to avoid calculating duplicates.
- Can we speed this up somehow?
Yes. 2x speedup is possible[1] for Forms with depth 2. However, the code only works for Objects, so the first non-Object proxy will halt the code. If you want to make it work for all objects, you'll have to use mirror primitives, which will reduce the speedup to about 1.25x.
- Do we need depth-messages for the "class analysis" protocol, too?
No idea, never really used SpaceTally :)
Levente
[1] I wrote some code using various optimizations. If you want me to, I can upload it to the Inbox with or without mirror primitives.
=============== Diff against System-topa.1174 ===============
Item was added:
- ----- Method: SpaceTally>>spaceForInstance:depth: (in category
'instance size') -----
- spaceForInstance: anObject depth: anInteger
- ^ self spaceForInstance: anObject depth: anInteger seen: IdentitySet
new!
Item was added:
- ----- Method: SpaceTally>>spaceForInstance:depth:seen: (in category
'instance size') -----
- spaceForInstance: anObject depth: anInteger seen: someObjects
- | class depth total |
- (someObjects includes: anObject) ifTrue: [^ 0].
- someObjects add: anObject.
- class := anObject class.
- depth := anInteger - 1.
- total := class isVariable
ifTrue: [class byteSizeOfInstanceOfSize: anObject basicSize]
ifFalse: [class isImmediateClass ifTrue: [0] ifFalse: [class
byteSizeOfInstance]].
- depth >= 0 ifTrue: [
anObject isCompiledCode
ifTrue: [
anObject literalsDo: [:literal |
total := total + (self spaceForInstance: literal depth: depth
seen: someObjects)]]
ifFalse: [
1 to: anObject basicSize do: [:index |
total := total + (self spaceForInstance: (anObject basicAt: index)
depth: depth seen: someObjects)].
1 to: class instSize do: [:index |
total := total + (self spaceForInstance: (anObject instVarAt:
index) depth: depth seen: someObjects)]]].
- ^ total!
Item was added:
- ----- Method: SpaceTally>>spaceForInstancesOf:depth: (in category
'instance size') -----
- spaceForInstancesOf: aClass depth: aNumber
- "Answer a pair of the number of bytes consumed by all instances of the
given class, including their object headers, and the number of instances. Follow each instance's fields up to the given depth. Beware of cycles to shared objects, which will tamper the resulting numbers.
- SpaceTally new spaceForInstancesOf: Form depth: 0. --- Same as
#spaceForInstanecsOf:
- SpaceTally new spaceForInstancesOf: Form depth: 1. --- Includes memory
footprint for bits etc.
- SpaceTally new spaceForInstancesOf: Form depth: 2. --- Also includes
LargePositiveIntegers in bitmaps ;-)
- "
- | instances total sub depth |
- instances := aClass allInstances.
- instances isEmpty ifTrue: [^#(0 0)].
- total := 0.
- instances do: [:each | total := total + (self spaceForInstance: each
depth: aNumber)].
- ^{ total. instances size }!
-- Sent from: http://forum.world.st/Squeak-Dev-f45488.html
squeak-dev@lists.squeakfoundation.org