Search expression for Code Critic

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

Search expression for Code Critic

andermoo
Hi,

what would be the correct search expression for SmallLint to find the  
following pattern:

condition
   ifTrue:[ ^result1 ]
   ifFalse:[ ^result2 ]

or:

condition
   ifTrue:[ ^result1 ].
^result2

in order to replace it with

^condition
   ifTrue:[ result1 ]
   ifFalse:[ result2 ]

I tested with VisualPart>>topComponent and interestingly the last form  
turned out to be around 10% faster than the first. In certain hot  
spots of an application, this could add up and make a difference.  
Apart from the performance aspect, the last form is also more  
functional style and less intention revealing (the intention being  
that "condition" actually decides upon the return value).

Therefore I thought it would be a good idea to add this pattern to the  
Code Critic set of rules. The search pattern, of course, should allow  
any number of statements prior to result1/2.

Any suggestions?

Andre


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Search expression for Code Critic

Holger Kleinsorgen-4
  search rule 1:

`@condition
    ifTrue:[ ^`@result1 ]
    ifFalse:[ ^`@result2 ]

search rule 2:

`@condition
    ifTrue:[ ^`@result1 ].
  ^ `@result2

replace with:

^ `@condition
    ifTrue: [ `@result1 ]
    ifFalse: [ `@result2 ].


> Hi,
>
> what would be the correct search expression for SmallLint to find the
> following pattern:
>
> condition
>     ifTrue:[ ^result1 ]
>     ifFalse:[ ^result2 ]
>
> or:
>
> condition
>     ifTrue:[ ^result1 ].
> ^result2
>
> in order to replace it with
>
> ^condition
>     ifTrue:[ result1 ]
>     ifFalse:[ result2 ]
>
> I tested with VisualPart>>topComponent and interestingly the last form
> turned out to be around 10% faster than the first. In certain hot
> spots of an application, this could add up and make a difference.
> Apart from the performance aspect, the last form is also more
> functional style and less intention revealing (the intention being
> that "condition" actually decides upon the return value).
>
> Therefore I thought it would be a good idea to add this pattern to the
> Code Critic set of rules. The search pattern, of course, should allow
> any number of statements prior to result1/2.
>

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Search expression for Code Critic

andermoo
Thanks Holger.

Me stupid. I missed the point that names used for matching are  
arbitrary. Expecting a syntax behind the names confused me. It's  
really simple. Now this is the complete rule, which also allows none  
or more statements before the returns:

redundantReturns
^self
   createParseTreeRule: #(
     '`@condition ifTrue:[ `@.Statements1. ^`@result1 ] ifFalse:
[ `@.Statements2. ^`@result2 ]'
     '`@condition ifTrue:[ `@.Statements1. ^`@result1 ]. ^`@result2'
   )
   name: (#UnnecessaryReturns << #browser >> 'Unnecessary returns from  
both ifTrue:ifFalse blocks') asString

Andre

BTW: As a sidenote to the tools team: Gathering the rules from class  
protocol names seems a bit unintuitive and not robust wrt general  
refactoring (not found by looking for senders). I'd rather suggest to  
tag rule definitions with a pragma.

--
Am 15.08.2010 um 00:25 schrieb Holger Kleinsorgen:

>  search rule 1:
>
> `@condition
>    ifTrue:[ ^`@result1 ]
>    ifFalse:[ ^`@result2 ]
>
> search rule 2:
>
> `@condition
>    ifTrue:[ ^`@result1 ].
>  ^ `@result2
>
> replace with:
>
> ^ `@condition
>    ifTrue: [ `@result1 ]
>    ifFalse: [ `@result2 ].
>
>
>> Hi,
>>
>> what would be the correct search expression for SmallLint to find the
>> following pattern:
>>
>> condition
>>    ifTrue:[ ^result1 ]
>>    ifFalse:[ ^result2 ]
>>
>> or:
>>
>> condition
>>    ifTrue:[ ^result1 ].
>> ^result2
>>
>> in order to replace it with
>>
>> ^condition
>>    ifTrue:[ result1 ]
>>    ifFalse:[ result2 ]
>>
>> I tested with VisualPart>>topComponent and interestingly the last  
>> form
>> turned out to be around 10% faster than the first. In certain hot
>> spots of an application, this could add up and make a difference.
>> Apart from the performance aspect, the last form is also more
>> functional style and less intention revealing (the intention being
>> that "condition" actually decides upon the return value).
>>
>> Therefore I thought it would be a good idea to add this pattern to  
>> the
>> Code Critic set of rules. The search pattern, of course, should allow
>> any number of statements prior to result1/2.
>>
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Search expression for Code Critic

John Brant-2
On 8/15/2010 5:16 AM, andermoo wrote:

> Me stupid. I missed the point that names used for matching are  
> arbitrary. Expecting a syntax behind the names confused me. It's  
> really simple. Now this is the complete rule, which also allows none  
> or more statements before the returns:
>
> redundantReturns
> ^self
>    createParseTreeRule: #(
>      '`@condition ifTrue:[ `@.Statements1. ^`@result1 ] ifFalse:
> [ `@.Statements2. ^`@result2 ]'
>      '`@condition ifTrue:[ `@.Statements1. ^`@result1 ]. ^`@result2'
>    )
>    name: (#UnnecessaryReturns << #browser >> 'Unnecessary returns from  
> both ifTrue:ifFalse blocks') asString

The second expression only matches two statements instead of a list of
statements that ends with the two statements. To fix that you need to
add "|`@temps| `@.Statements0." to the beginning of your expression.

If you want to transform the multiple returns into a single return, you
can look at the expressions in the InlineMethodRefactoring class. In
particular, look at normalizeIfTrues and normalizeReturns. The
normalizeIfTrues method transforms your second case into your first and
the normalizeReturns transforms the first case into a single
ifTrue:ifFalse: return. You may want to change the patterns in
normalizeIfTrues somewhat as they will eliminate guard clauses.


John Brant
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Search expression for Code Critic

Jan Weerts
In reply to this post by andermoo
Hi!

On 14.08.2010 19:36, andermoo wrote:

> Hi,
>
> what would be the correct search expression for SmallLint to find the
> following pattern:
>
> condition
>     ifTrue:[ ^result1 ]
>     ifFalse:[ ^result2 ]
>
> or:
>
> condition
>     ifTrue:[ ^result1 ].
> ^result2
>
> in order to replace it with
>
> ^condition
>     ifTrue:[ result1 ]
>     ifFalse:[ result2 ]
>
> I tested with VisualPart>>topComponent and interestingly the last form
> turned out to be around 10% faster than the first. In certain hot
> spots of an application, this could add up and make a difference.
> Apart from the performance aspect, the last form is also more
> functional style and less intention revealing (the intention being
> that "condition" actually decides upon the return value).

Without questioning the style aspect, I wonder how you measured that
10% performance boost. Because in the simplest form of method, like
        ^ boolean
                ifTrue: [ 1 ]
                ifFalse: [ 2 ]
the bytecodes for its variations (two alternate returns or two returns
with a guard clause) are exactly the same:
   1 <00> push inst 0
   2 <C1> jump false 5
   3 <4A> push 1
   4 <65> return
   5 <4B> push 2
   6 <65> return
for the three variants. The only measurable execution time differences
even depend on order of execution after creation of the object
understanding this method.

Regards
   Jan
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Search expression for Code Critic

andermoo

Am 16.08.2010 um 07:35 schrieb Jan Weerts:

> Without questioning the style aspect, I wonder how you measured that  
> 10% performance boost. Because in the simplest form of method, like
> ^ boolean
> ifTrue: [ 1 ]
> ifFalse: [ 2 ]
> the bytecodes for its variations (two alternate returns or two  
> returns with a guard clause) are exactly the same:
>  1 <00> push inst 0
>  2 <C1> jump false 5
>  3 <4A> push 1
>  4 <65> return
>  5 <4B> push 2
>  6 <65> return
> for the three variants. The only measurable execution time  
> differences even depend on order of execution after creation of the  
> object understanding this method.
>
> Regards
>  Jan

Hi Jan,

thanks for pointing this out. Ha! I fell for a simple measurement  
mistake. I repeated the measurement this morning, and it still seemed  
to be there, which completely puzzled me. I picked a deeply nested  
VisualPart from an open window with the inspector and did the test for  
#VisualPart>>topComponent:

    Time millisecondsToRun:[ 100000000 timesRepeat:[ self  
topComponent ]].

Ran that test 10 times and took the average. The difference is a  
little less than yesterday (~8%), but it's still there and  
reproduceable. Considering the identical bytecodes, there should not  
be any difference, or at least occur for both variants with the same  
probability.

Now, my mistake was to not take the garbage collector into account. As  
I always tested in the same order, for the second test, the GC had  
more work to do!

I missed to check the most obvious first, the bytecodes, before doing  
any measurement. I should stick with my apps and GUIs and keep my  
hands off this kind of minimalist tweaking ;-)

Andre

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc