Re: Reducers in Smalltalk - template clean blocks

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

Re: Reducers in Smalltalk - template clean blocks

Paul Baumann
>> >> Reducer filter: filterBlock
>>
>> generates a block on #reduce:init: similar to:
>>
>> >> transform: reduceBlock
>> >>    ^[:result :each |
>> >>       (filterBlock value: each)
>> >>          ifTrue: [reduceBlock value: result value: each]
>> >>          ifFalse: [result]]
>>
>> Even if filterBlock and reduceBlock are clean and will not change, the transformation
>> yields a copying block that executes slower than >> a clean one.

You mentioned CollectionViews. I use generated blocks in that code. When client code asks GS for information then a clean query block is created to gather that information for each item in the collection being enumerated. The block allows context to be passed as arguments into it so that it remains clean while still being able to resolve anything that is needed. The savings is that the context object need only be created once for all the items being enumerated and that the code being performed each time is as efficient as the compiler can create.

>> I did some experiments with decompiling the clean input blocks and
>>  compiling a clean transformed block. However this proved to
>> be >> far too slow for serious application.

Yeah, that would be slow.

>> It would be nice to just inline/insert the compiled clean blocks in
>> an already compiled transformation block. But I don't know
>>  whether >> this is possible at all.
>> Do you have any ideas?

Yes, and you've hinted at the solution that can be used when blocks have little to change. You can use a clean block as a template for creating other clean blocks. You copy the clean block and replace an easily recognized literal with the with a different selector to execute. It avoids having to compile a block every time. This kind of tuning varies by Smalltalk dialect (if that is a concern). I've done things like this a couple times. It works well once you figure out all the tricks for the development environment. Make sure that you can debug it without confusing the debugger. To do that with VW you need to copy from the CompiledMethod down to where the replacement block is referenced. The cost of code generation and compile is reduced to copying a graph of three objects.

To keep it clean, you likely want to pass the argument (or some context object you can get the receiver from) into the block. You can implement these as class methods to play with:

templateBlock_oneArgument
        "       self templateBlock_oneArgument "

        ^[:receiver :arg1 | receiver templateSelector: arg1 ]

templateBlock_oneArgument_templateSelector: aSelector
        "       (self templateBlock_oneArgument_templateSelector: #with:)
                        value: OrderedCollection value: #test.
        "
        "       (self templateBlock_oneArgument_templateSelector: #halt:)
                        value: OrderedCollection value: #test.
        "

        | aBlock aCompiledBlock cm |
        aBlock := self templateBlock_oneArgument.
        aCompiledBlock := aBlock method copy.
        cm := aCompiledBlock outerMethod copy.
        cm at: 1 put: aCompiledBlock.
        aCompiledBlock outerMethod: cm.
        1 to: aCompiledBlock size do: [:slot |
                (aCompiledBlock at: slot) == #templateSelector:
                ifTrue: [aCompiledBlock at: slot put: aSelector].
        ].
        ^aBlock copy method: aCompiledBlock

The code above would be more maintainable to defining a CompiledMethod>>copyForTemplate method that deep copies the graph of objects related to the block, but this is simple to show.

Tricks like the one shown above can help performance a lot in some situations, but can also ruin performance in others. It has to be applied judiciously. The cost of deep copying the CompiledMethod is not something that you want to happen more often than you need.

Paul Baumann




This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.


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