ct6502 / apple2ts

Apple II Emulator in TypeScript
Creative Commons Attribution Share Alike 4.0 International
62 stars 10 forks source link

Perf Question : Lookup table vs switch #23

Closed kktos closed 1 year ago

kktos commented 1 year ago

I watched the presentation Chris made at VCF and I was curious about the change made for the softswitches. The choice was to use a lookup table. And it has raised my interest as it is a usual problem we have with js ;) And, guess what, most if the time, if not always, the switch is faster. ok, ok, we're not chasing cycles here (;)) but have you tried both solutions ? (I do love what you did. pretty neat)

ct6502 commented 1 year ago

Excellent question! One side note - the talk was actually at KansasFest, not VCF.

As noted in the presentation, I tried two different approaches for softswitches. The issue is how to look up the correct memory address, given that you might have softswitches which tell the Apple IIe to look in main memory, auxiliary memory, ROM vs RAM, which bank of banked memory, etc.

The first way was to just use a giant series of "if" statements. Every time a memory access was made (which is pretty much for every CPU instruction, sometimes multiple times), it would run thru a "memget" or "memset" routine, and it would examine all of these softswitches to narrow down the choice. Then it would finally pull the value out of the appropriate array (or store it for memset).

The next (and current) way is to have a lookup table, which uses the "high" byte of the memory address as an index into a lookup table. The value in the lookup table then points to a particular location in a giant array which contains all of the possible memory locations. The lookup table is only updated when a softswitch is changed. It's a bit more work to rebuild the lookup table, but that happens a lot less often then just a regular memget/memset.

Anyway... I did speed comparisons when I made the change. I was expecting a huge benefit, maybe a factor of 2 or more. Surprisingly (to me), the lookup table method was only about 20% faster. If I recall, I tried this under "normal" code runs. I'm sure the results would get either better (or worse) depending upon how quickly softswitches were being thrown.

Still, even though it wasn't a huge improvement, it feels a lot better to be going thru a lookup table rather than a giant messy set of nested if/then/else statements. So I'm good with the new implementation.