If I only was at that Smalltalk Superpowers thing again. Here's an interesting "pattern" I played with earlier today, and profiled this evening.
The Use Case
Somewhere, in a piece of code, someone writes some code which looks kind of like a case statement. A sequence of computations, the first of which returns a positive result, results in the computation of some sort of result object. For testing/example purposes, I put together an arbitrary example:
caseStatement
	
	(input between: 0 and: 0.2) ifTrue: [^1].
	(input between: 0.1 and: 0.3) ifTrue: [^2].
	(input between: 0.2 and: 0.4) ifTrue: [^3].
	(input between: 0.3 and: 0.5) ifTrue: [^4].
	(input between: 0.4 and: 0.6) ifTrue: [^5].
	(input between: 0.5 and: 0.7) ifTrue: [^6].
	(input between: 0.6 and: 0.8) ifTrue: [^7].
	(input between: 0.7 and: 0.9) ifTrue: [^8].
	(input between: 0.8 and: 1.0) ifTrue: [^9].
	^-1
The tests are all numeric ranges, and the return values are simple literals, to keep things simple. It could be any variety of tests though. I have a couple in mind, but I'll let you use your own imagination.
The Problem
When this becomes a problem, is when you suddenly need this to be more pluggable. Perhaps this is sort of tool, and someone needs to insert an
	(input between: 0.35 and: 0.55) ifTrue: [^(9/2)]
To do this, they have to patch the original method. But if the base developers make any changes to the original method later, those updates are lost when ever the patch is loaded. And heaven forbid if it's a popular place to patch and add one's own hooks into.
First Cut Solution
One way to solve this, is to break these individual test/return values up into separate methods. Using method tags, we can register methods that participate in this, and then we can write an aggregrated check thing. The individual methods look something like
case6
	
	<case>
	^(input between: 0.5 and: 0.7)
		ifTrue: [6]
		ifFalse: [nil]
And then we have a method that finds them all, and executes them in a specified order looking for the first match
slowCase
	
	| methods |
	methods := Pragma
		allNamed: #case
		in: self class
		sortedUsing: [:a :b | a selector < b selector].
	methods
		do: [:each | (self perform: each selector) ifNotNil: [:result | ^result]].
	self shouldNotImplement
This works like a charm. New modules can add new <case> tagged methods, and everyone is happy.
The only problem, is if you're original code needed to run at all quick. I tested these on a pretty fast machine (~4K Bogomips Linux box). At 1,000,000 reps, the original runs in just a second (~1060ms). Our flexible thing, runs in about 150s; I didn't leave out the 'm'. It's about 150 times slower.
If make it work, make it right, is enough, you don't need to keep going. It doesn't matter. But if the method was something that was getting pounded a lot and you're not excited about having something that was running at an acceptable speed, jump up by 150+ times it's old length, you start scratching your head.
Inlining
So one way we can make things go faster, is recognize that the handy Pragma services are expensive. It's allocating a new collection each time. Sorting them. Searching the whole method dictionary parametrically. We could exploit our knowledge of the Smalltalk execution objects and go a little faster. Something like
streamlinedDynamicCase
	
	self class getMethodDictionary
		keysAndValuesDo:
			[:selector :method | 
			| attributes |
			(attributes := method attributes) == nil
				ifFalse:
					[(attributes includesKey: #case)
						ifTrue:
							[| result |
							(result := self perform: selector) == nil ifFalse: [^result]]]].
	self shouldNotImplement
This brings us down to 
~7 seconds! I'm cheating in that I know the attributes are an IdentityDictionary. That all the methods are local (none inherited). And I've totally cheated by knowing that the linear storage of the MethodDictionary is going to have my case1, case2, case3, already sorted for me.
Taking a Hint from the VM
The above is a real speed jump. But it's mean and fast, still 7x slower, and I'd like to get back to the high level reflection afforded by Pragma object. One thing the VM is good about doing, is taking an "it's ok to do it once slow, if you do it faster after that" approach.
Using the method tags, gives us a nice entry point to know any time any of our <case> tagged methods change, get added to, or are removed. Depending on whether its class side or instance side, our object will receive a classMethodsChanged/instanceMethodsChanged any time one of these <case> tagged methods is added/removed/modified.
The thing to do is build up an object that removes any of the parts that don't need to be dynamic, and execute them as quickly as possible. A method like the following can do this for us
updateDynamicCaseBlock
	
	| ws caseMethods |
	ws := String new writeStream.
	ws nextPutAll: '[:object | | result | '.
	caseMethods := Pragma
		allNamed: #case
		in: self class
		sortedUsing: [:a :b | a selector < b selector].
	caseMethods
		do:
			[:each | ws nextPutAll: '(result := object ' , each selector , ') == nil ifTrue: ['].
	ws nextPutAll: 'self shouldNotImplement'.
	caseMethods size + 1 timesRepeat: [ws nextPut: $]].
	DynamicCaseBlock := Compiler evaluate: ws contents
We add a new class shared variable (DynamicCaseBlock) and then add our access point
blockDynamicCase
	^DynamicCaseBlock value: self
Does it pay off? It executes in 
1.2 seconds. So we end up with a pattern that pays a 20% speed penalty for having a pluggable mechanism for adding new query/result pairs. Not bad. If you need it. And if it's at a point where your browser lists are pounding at it for every display... you just might this kind of technique.