diff options
| author | Uri Shaked | 2020-12-12 15:01:17 +0200 |
|---|---|---|
| committer | Uri Shaked | 2020-12-12 15:01:17 +0200 |
| commit | e7ea8c76bd649aa84fdeb084fec02529743ee6eb (patch) | |
| tree | ffe520a2f308a61805b04ddfbc3432a71205159c /src/cpu/cpu.ts | |
| parent | test(cpu): fix implicit any error (diff) | |
| download | avr8js-e7ea8c76bd649aa84fdeb084fec02529743ee6eb.tar.gz avr8js-e7ea8c76bd649aa84fdeb084fec02529743ee6eb.tar.bz2 avr8js-e7ea8c76bd649aa84fdeb084fec02529743ee6eb.zip | |
perf(cpu): speed up event system
ditch `array.sort()` and instead manually keep the array sorted when we insert a new item.
Diffstat (limited to 'src/cpu/cpu.ts')
| -rw-r--r-- | src/cpu/cpu.ts | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/src/cpu/cpu.ts b/src/cpu/cpu.ts index e7a2544..a609222 100644 --- a/src/cpu/cpu.ts +++ b/src/cpu/cpu.ts @@ -173,23 +173,29 @@ export class CPU implements ICPU { } } - private updateClockEvents() { - this.clockEvents.sort((a, b) => a.cycles - b.cycles); - this.nextClockEvent = this.clockEvents[0]?.cycles ?? 0; - } - addClockEvent(callback: AVRClockEventCallback, cycles: number) { const entry = { cycles: this.cycles + Math.max(1, cycles), callback }; - this.clockEvents.push(entry); - this.updateClockEvents(); + // Add the new entry while keeping the array sorted + const { clockEvents } = this; + if (!clockEvents.length || clockEvents[clockEvents.length - 1].cycles <= entry.cycles) { + clockEvents.push(entry); + } else if (clockEvents[0].cycles >= entry.cycles) { + clockEvents.unshift(entry); + } else { + for (let i = 1; i < clockEvents.length; i++) { + if (clockEvents[i].cycles >= entry.cycles) { + clockEvents.splice(i, 0, entry); + break; + } + } + } + this.nextClockEvent = this.clockEvents[0].cycles; return callback; } updateClockEvent(callback: AVRClockEventCallback, cycles: number) { - const entry = this.clockEvents.find((item) => item.callback === callback); - if (entry) { - entry.cycles = this.cycles + Math.max(1, cycles); - this.updateClockEvents(); + if (this.clearClockEvent(callback)) { + this.addClockEvent(callback, cycles); return true; } return false; @@ -199,18 +205,22 @@ export class CPU implements ICPU { const index = this.clockEvents.findIndex((item) => item.callback === callback); if (index >= 0) { this.clockEvents.splice(index, 1); - this.updateClockEvents(); + this.nextClockEvent = this.clockEvents[0]?.cycles ?? 0; + return true; } + return false; } tick() { - if (this.nextClockEvent && this.nextClockEvent <= this.cycles) { - const clockEvent = this.clockEvents.shift(); - clockEvent?.callback(); - this.nextClockEvent = this.clockEvents[0]?.cycles ?? 0; + const { nextClockEvent, clockEvents } = this; + if (nextClockEvent && nextClockEvent <= this.cycles) { + clockEvents.shift()?.callback(); + this.nextClockEvent = clockEvents[0]?.cycles ?? 0; } - if (this.interruptsEnabled && this.nextInterrupt >= 0) { - const interrupt = this.pendingInterrupts[this.nextInterrupt]; + + const { nextInterrupt } = this; + if (this.interruptsEnabled && nextInterrupt >= 0) { + const interrupt = this.pendingInterrupts[nextInterrupt]; avrInterrupt(this, interrupt.address); if (!interrupt.constant) { this.clearInterrupt(interrupt); |
