Gathering statistics on messages sent to an object

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Gathering statistics on messages sent to an object

alistairgrant
If you subscribe to pharo-dev you will have seen that I've been looking
at the primitives used in DiskStore.

As part of that investigation I wanted to get an idea of which messages
are typically sent to DiskStore and how often.

Denis Kudriashov provided a neat package that implements a "halt on
next object call".  I've been wanting to play with the package for a
while and decided this was a good opportunity.

I've extended that package to keep count of how many times messages are
sent to a target object, e.g.:



| point trace |

point := 2@3.
trace := ExternalSendStats logStatsFor: point.
point
        x;
        y;
        angle;
        x.
trace stats.
"a Dictionary(
        #angle->1
        #x->2
        #y->1 )"



The package is probably too simplistic, and there's bound to be other
ways to do this, but it met my immediate needs and gave me a chance to
try out the Ghost package.  I'll extend it if and when I need to.

Many thanks to Denis for making the Ghost package available, and
hopefully this is useful for someone, or at least triggers some new
ideas.

Denis' original article is at: http://dionisiydk.blogspot.cz/2016/04/halt-next-object-call.html

The extensions can be installed with:

Metacello new
        baseline: 'AkgGhost';
        repository: 'github://akgrant43/akg-ghost:master/mc';
        load



Cheers,
Alistair

Reply | Threaded
Open this post in threaded view
|

Re: Gathering statistics on messages sent to an object

Denis Kudriashov
Hi Alistair.

Do you know that you are able to count any message send? (not only external).
For this you need prevent meta recursion. Now inside message processing you do:
aMessage sendTo: anObject
which produces another intercepting message #perform:withArguments which repeats original message send.
Fortunately Ghost handles such kind of meta recursion and there is no infinite loop here: any self-sends are ignored in such cases.

If you want intercept any message try following code:
ExternalSendTrace>>send: aMessage to: anObject
| method |
announcer announce: (ExternalSendAnnouncement message: aMessage trace: self).
method := anObject class lookupSelector: aMessage selector.
^GHMetaMessages executeWith: anObject andArguments: aMessage arguments method: method 

In that case we lookup and execute method by using mirror primitive which not sends any message to object.

For example:

rect := 10@30 corner: 100@300.
trace := ExternalSendStats logStatsFor: rect.
rect area.
trace stats.
 "a Dictionary(#area->1 #height->1 #width->1 )"


Best regards,
Denis


2017-04-24 14:43 GMT+02:00 Alistair Grant <[hidden email]>:
If you subscribe to pharo-dev you will have seen that I've been looking
at the primitives used in DiskStore.

As part of that investigation I wanted to get an idea of which messages
are typically sent to DiskStore and how often.

Denis Kudriashov provided a neat package that implements a "halt on
next object call".  I've been wanting to play with the package for a
while and decided this was a good opportunity.

I've extended that package to keep count of how many times messages are
sent to a target object, e.g.:



| point trace |

point := 2@3.
trace := ExternalSendStats logStatsFor: point.
point
        x;
        y;
        angle;
        x.
trace stats.
"a Dictionary(
        #angle->1
        #x->2
        #y->1 )"



The package is probably too simplistic, and there's bound to be other
ways to do this, but it met my immediate needs and gave me a chance to
try out the Ghost package.  I'll extend it if and when I need to.

Many thanks to Denis for making the Ghost package available, and
hopefully this is useful for someone, or at least triggers some new
ideas.

Denis' original article is at: http://dionisiydk.blogspot.cz/2016/04/halt-next-object-call.html

The extensions can be installed with:

Metacello new
        baseline: 'AkgGhost';
        repository: 'github://akgrant43/akg-ghost:master/mc';
        load



Cheers,
Alistair


Reply | Threaded
Open this post in threaded view
|

Re: Gathering statistics on messages sent to an object

alistairgrant
Hi Denis,

On Mon, Apr 24, 2017 at 03:48:46PM +0200, Denis Kudriashov wrote:

> Hi Alistair.
>
> Do you know that you are able to count any message send? (not only external).
> For this you need prevent meta recursion. Now inside message processing you do:
>
>     aMessage sendTo: anObject
>
> which produces another intercepting message #perform:withArguments which
> repeats original message send.
> Fortunately Ghost handles such kind of meta recursion and there is no infinite
> loop here: any self-sends are ignored in such cases.
>
> If you want intercept any message try following code:
>
>     ExternalSendTrace>>send: aMessage to: anObject
>     | method |
>     announcer announce: (ExternalSendAnnouncement message: aMessage trace:
>     self).
>     method := anObject class lookupSelector: aMessage selector.
>     ^GHMetaMessages executeWith: anObject andArguments: aMessage arguments
>     method: method
>
>
> In that case we lookup and execute method by using mirror primitive which not
> sends any message to object.
>
> For example:
>
>
>     rect := 10@30 corner: 100@300.
>     trace := ExternalSendStats logStatsFor: rect.
>     rect area.
>     trace stats.
>      "a Dictionary(#area->1 #height->1 #width->1 )"
>
>
>
> Best regards,
> Denis

Thanks for the exmplanation and code.  In this particular case I wanted
to specifically exclude internal message sends, as the goal was to find
out how other objects called DiskStore, but this will obviously be
useful in different situations.

Thanks again!
Alistair


> 2017-04-24 14:43 GMT+02:00 Alistair Grant <[hidden email]>:
>
>     If you subscribe to pharo-dev you will have seen that I've been looking
>     at the primitives used in DiskStore.
>
>     As part of that investigation I wanted to get an idea of which messages
>     are typically sent to DiskStore and how often.
>
>     Denis Kudriashov provided a neat package that implements a "halt on
>     next object call".  I've been wanting to play with the package for a
>     while and decided this was a good opportunity.
>
>     I've extended that package to keep count of how many times messages are
>     sent to a target object, e.g.:
>
>
>
>     | point trace |
>
>     point := 2@3.
>     trace := ExternalSendStats logStatsFor: point.
>     point
>             x;
>             y;
>             angle;
>             x.
>     trace stats.
>     "a Dictionary(
>             #angle->1
>             #x->2
>             #y->1 )"
>
>
>
>     The package is probably too simplistic, and there's bound to be other
>     ways to do this, but it met my immediate needs and gave me a chance to
>     try out the Ghost package.  I'll extend it if and when I need to.
>
>     Many thanks to Denis for making the Ghost package available, and
>     hopefully this is useful for someone, or at least triggers some new
>     ideas.
>
>     Denis' original article is at: http://dionisiydk.blogspot.cz/2016/04/
>     halt-next-object-call.html
>
>     The extensions can be installed with:
>
>     Metacello new
>             baseline: 'AkgGhost';
>             repository: 'github://akgrant43/akg-ghost:master/mc';
>             load