stoop 300-block optimizationinvw
out of 17
Post on 29-Nov-2014
Embed Size (px)
- 1. Blocks and Optimization in VW
- [ :x :y | |tmp| ...]
- value: value:
- value: value: value:
- In VisualWorks there are four types of blocks:
- Full Blocks
- Copying Blocks
- Clean Blocks
- Inlined Blocks
- The programmer does not have to explicitly mention.
- Inferred by the compiler. However, knowing the subtle differences allows the programmer to write more efficient code.
- Read and assign temporary variables.
- Block containing explicit return ^.
- Compiled in a BlockClosure.
- Evaluation by the creation of an explicit MethodContext or BlockContext object instead of using a pseudo-object contained in the stack.
- Most costly
- Instead of:
- m1: arg1 m1: arg1
- arg1 isNil ^ arg1 isNil
- ifTrue: [^ 1] ifTrue: 
- ifTrue: [^ 2] ifTrue: 
- Read temporary variables but do not assign them.
- No explicit return.
- Access instance variables of self and assign them.
- Not compiled into a BlockClosure.
- They are compiled by copying every access into the block, thus avoiding explicit references to a context where the copied variables appear.
- Their arguments and temporaries are merged into the enclosing methods context as compiler-generated temporaries.
- Contain only reference block temporary variables or global variables.
- No reference to self or to instance variables.
- nodes do: [:each | each name = #stef]
- nodes select: [:each | each isLocal]
- Code of certain methods, like whileFalse: ifTrue:, is directly inlined into the code of the calling method.
- The literal blocks (without arguments) passed as argument to such methods are also inlined in the byte-code of the calling method.
- Inlined methods are whileTrue, whileTrue:, whileFalse, whileFalse:, and: or:, ifTrue:, ifFalse:, ifTrue:ifFalse:, ifFalse:ifTrue:, to:do:, to:do:by:
- Look in MessageNode>>transform* methods to see the inlining
- 1 to: 5 do: [:x| ]
- Compiled into :
- | t1 |
- t1 := 1.
- [t1 >, aSequenceableCollection
- "Answer a copy of the receiver concatenated with the argument,
- a SequenceableCollection."
- ^self copyReplaceFrom: self size + 1
- to: self size
- with: aSequenceableCollection
- SequenceableCollection>>copyReplaceFrom: start to: stop with: replacementCollection
- "Answer a copy of the receiver satisfying the following conditions:
- Suppose that we want to concatenate a pretty long list of strings, for example the keys of the Smalltalk dictionary.
- bigString := String new.
- Smalltalk keys do: [:aString | bigString := bigString, aString].
- Here the assignment of bigString leads to a Full Block
- We can suppress the assignment like that and thus obtain a clean block
- aStream:= WriteStream on: String new.
- Smalltalk keys do: [:aString | aStream nextPutAll: aString].
- inject:into: allows us to suppress the reference to variables that are outside the block and to obtain a clean block.
- aStream:= WriteStream on: String new.
- Smalltalk keys inject: aStream
- into: [:cumul :aString| cumul nextPutAll: aString. cumul]
- Instance Variables:
- "Clean" closure with no references to anything from outer scopes. A clean closure has outerContext = nil and copiedValues = empty Array.
- "Copying" closure that copies immutable values from outer scopes when the closure is created. A copying closure has outerContext = nil and copiedValues = Object or Array.
- "Full" closure that retains a reference to the next outer scope. A full closure has outerContext ~= nil and copiedValues = nil.
- As an optimization, copiedValues holds the single copied value if there is exactly one, or an Array of values if there is more than one. Note that if there is a single copied value, the value being copied can be nil, so testing for nil in copiedValues is not a reliable means of classifying closures. The way to check whether a closure has copied values is to ask its method whether numCopiedValues > 0.
- Now if we use a stream for the Smalltalk keys we can avoid an iteration method. With whileFalse: that is inlined the block itself will be inlined.
- |aReadStream aWriteStream|
- aReadStream := ReadStream on: Smalltalk keys asArray.
- aWriteStream := WriteStream on: String new.
- [aReadStream atEnd] whileFalse: [aWriteStream nextPutAll: a ReadStream next].
- Optimization Yes, but Readibility First
- 17. Summary
- Try to define clean blocks
View more >