From: Dean Swan@MITEL on 04/25/2000 11:56 AM
Okay, I took a crack at it. The blocks can be removed without making things messy. In general, I divided up SimpleGeneticAlgorithm into 3-4 classes. Here are the particulars:
Lex,
Thanks. I'll try to take a look at what you've done over the next few days.
I toyed with it about 15 minutes, to try and duplicate the trick in #fieldAt:width:, but ultimately I gave up. :| I'm sure someone who knows BitBlt better could fix this right up and get performance back up.
That took me quite a while to get right, several hours, at least. The inspiration for this was taken from BitBlt>>bitPeekerFromForm:. I imagine the put could be done in a similar fashion, using BitBlt>>bitPokerToForm: as a model, and it is *very* worthwhile, because the speed difference for fields that are less than 30 bits wide is dramatic.
As I said, I'll have to play around with what you've done. Speed is extremely important for genetic algorithms, since for non-trivial applications, you may have to run it for thousands or even millions of generations (assuming you start from a completely random population) to get a usable answer.
...several methods can get simpler--for example, swapChromosome:with: is now just a couple of gets and a couple of sets, instead of 3 BitBlt operations.
I'm not to sure this is a good idea. Certainly, this is conceptually cleaner, but gets and sets ultimately end up sending fieldAt:width: and fieldAt:width:put:, which end up doing a lot more than three BitBlts, even if the puts are optimized in the same way that the gets are. It also involves more message sends, which are a major bottleneck for Squeak, because even my fastest Mac (my wife's iMac G3/333), and my fastest PC (PII/450) only crank a little over a million sends/second. ...And, BitBlt is fast. That's why I went with encoding the chromosomes in a form to begin with, in spite of my misgivings about the obtuseness of the implementation.
I have to admit the need to reference the original instance of the SimpleGeneticAlgorithm has always bothered me. It's a kind of circular reference thing that just feels "messy".
I'll see if I can do anything to get the speed back up, but my original whack at it was primarily focused on making the code small and fast, at the expense of transparency of design and readability.
Changing the block to a method didn't seem to hurt things, and the non-local features of blocks turned out not to be needed.
Keep in mind that the class comment demonstrates an absolutely trivial application. My real application does involve some other non-local references to objects that represent the search target, and they are *very* expensive to compute, so they would have to be made visible to the evaluator method by some means (class pools? - ick) because recomputing them for every reference is just out of the question. I still haven't found very good answers for my target problem, and I've let this thing crank for days on my fastest machines.
Exchanges like this is one of the many reasons I'm so attracted to Squeak. 99% of the code I write never gets read by anybody but me. My employer only cares if it "meets the spec", and gets done on time. (They're not really that brash, but those really are the major things that count come annual review time). Actually, they also care about cost targets, so I suppose I get indirectly graded on target hardware design also. Such is life developing embedded firmware. It also leads to code which places performance and resource minimization at the top of the priority list, which often leads to less than totally transparent and obvious designs.
I'm still inclined to think that blocks are one of the more powerful (and thus dangerous) constructs in Smalltalk, and I for one don't want to see them go away.
Thanks Again!
-Dean Swan dean_swan@mitel.com
A remark to this thread:
Dean_Swan@Mitel.COM wrote:
As I said, I'll have to play around with what you've done. Speed is
extremely important for genetic algorithms, since for non-trivial applications, you may have to run it for thousands or even millions of generations (assuming you start from a completely random population) to get a usable answer.
It's true that speed is important for evolutionary algorithms.
I have used them for optimization of image processing operations. In this area the to be optimized evaluation function tooks almost whole of the computation time, time consumed in EA algorithms outside the evaluation function was negligible.
So for *me* flexibility and readability have priority over the last bit of speed regarding EA implementations (outside the evaluation function).
Greetings,
Stephan
squeak-dev@lists.squeakfoundation.org