Newsgroups: comp.lang.smalltalk
Path: cantaloupe.srv.cs.cmu.edu!rochester!udel!news.mathworks.com!newsfeed.internetmci.com!chi-news.cic.net!nntp.coast.net!torn!nott!cunews!dbuck
From: dbuck@superior.carleton.ca (Dave Buck)
Subject: Re: Debug checking code
X-Nntp-Posting-Host: superior.carleton.ca
Message-ID: <DJsII1.76o@cunews.carleton.ca>
Sender: news@cunews.carleton.ca (News Administrator)
Organization: Carleton University, Ottawa, Canada
References: <4b2akm$o82@fountain.mindlink.net> <4b4052$orr@watnews2.watson.ibm.com>
Date: Mon, 18 Dec 1995 16:15:36 GMT
Lines: 70

In article <4b4052$orr@watnews2.watson.ibm.com>,
David N. Smith  <dnsmith@watson.ibm.com> wrote:
>In article <4b2akm$o82@fountain.mindlink.net> Ian upright,
>ian@ican.mlnet.com writes:
>
>>The someMethod takes nearly 5 times as long as does someMethod2.  This
>>isn't as good as C++ in terms of being able to just put IFDEFS or
>>macros so that the compiler will ignore the code.  I suppose better
>>compiler optimization would help. (not within my control, obviously)
>>Is there a better way of doing this that I don't know about?
>
>I think the problem has to do with block optimizations. Here are two
>tests using VisualWorks 2.0.

You are quite correct that sending a message to a block is much slower
than doing an ifTrue: to branch around the block.  This is the major
cause of the slow-down.  Another cause is that Smalltalk can optimize
the calls to methods that just return or set an instance variable,
return a literal, or return self.

I ran the following methods about 10,000,000 times on my 75 MHz
Pentium and timed them (VisualWorks 2.0):

test
    ^a
    "Execution time: 2.3 seconds"

test
    false ifTrue: [self error: 'hello'].
    ^a
    "Execution time: 5.8 seconds"

test
   [self error: 'hello'] yourself.
    ^ a

    "Execution time: 19.2 seconds"

   "yourself also exists, it's
   simpler than outerContext, and it provides yet another use for the
   'yourself' message (as was asked in another thread.  ;-)"

There's a totally non-intrusive solution that's still fairly
packagable.  Unfortunately, it's not quite perfect.

Create a Debug class which proxies the real class.  The debug class
overrides doesNotUnderstand: and delegates to the real class.  For
methods that you want to write debugging code for, write them in the
debugging class, then delegate to the real class.  You can then
over-ride the real classes' 'new' method to return the debug class and
use it wherever you used the original class.

This doesn't work in the following cases:
   - messages sent to self
   - messages sent to super
   - class methods
   - methods where the debug code is not at the start or end of the
method

This technique is a bit hairy and involves a few more details that I
haven't mentioned here.  It's not recommended for the faint of heart.

David Buck
dbuck@ccs.carleton.ca

_________________________________
| David K. Buck                 |
| dbuck@ccs.carleton.ca         |
| The Object People             |
|_______________________________|
