Puzzle 9: Release the bug.
In this puzzle we shall look at a benchmarking script which contains a significant error, which causes incorrect results for the last test snippet. The test measures the time it takes to free
count := 50000 instances of the class
Task. All instances are stored
internally in the array
Task.List, hence in order to invoke
__delete they must be removed from this array.
Puzzle objectives: Correct the significant mistake in the benchmarking script in the code box below.
Puzzle rules: You are not allowed to modify the class
Task. You must be able to explain the mistake, hence, why your solution works.
Puzzle hint: When you correct the mistake, you can expect the last test snippet to be significantly faster. Edit: When you correct the mistake, you can expect the last test to work as intended.
Code:
The code comes from this discussion:
[BUG]Associative Arrays, you are not required to read the discussion to solve the problem. Reading others' code and debug it can be very challenging, I consider that part of this puzzle and therefore I have not removed any noise from the code.
Code: Select all
; https://autohotkey.com/boards/viewtopic.php?f=37&t=42328
; [BUG]Associative Arrays
setbatchlines,-1
#noenv
class Task {
static time:= 0
static tick:= 0
static List:= []
__new(name, mode:= 0x13) {
this.mode:= mode
this.name:= name
Task.List[this]:= "" ;no value for key
}
end() { ;initate destruct
if !Task.time
Task.time:= A_TickCount
Task.List.Delete(this) ;self kill
}
;Task.List.Delete(this)
;Task.List:= ""
__delete() { ;destruct idea by Helgef
if !Task.time
Task.time:= A_TickCount
this.name:= ""
Task.tick:= A_TickCount - Task.time
}
}
result:= ""
count:= 50000
; SLOW -----------------------------------------------
loop % count
new Task("name" A_Index)
Task.time:= ""
SLOW:
for key in Task.List {
key.end()
goto SLOW
}
key:=""
msgBOX(result.= "SLOW`t:= " Task.tick "`n")
; FAST -----------------------------------------------
array:= []
loop % count
new Task("name" A_Index)
Task.time:= ""
for key in Task.List
array[A_Index]:= key
loop % array.length()
array[A_Index].end()
array:= ""
key:=""
msgBOX(result.= "FAST`t:= " Task.tick "`n")
; ENUM -----------------------------------------------
loop % count
new Task("name" A_Index)
Task.time:= ""
while (_enum:= Task.List._newEnum()).Next(key, val) {
loop {
key.end()
} until !_enum.Next(key, val)
}
key:=""
msgBOX(result.= "ENUM`t:= " Task.tick "`n")
; LOOP -----------------------------------------------
loop % count
new Task("name" A_Index)
Task.time:= ""
loop {
isEmpty:= 1
for key in Task.List {
key.end()
isEmpty:= 0
}
} until isEmpty
key:="" ; <-- edit: conversion mistake fixed
msgBOX(result.= "LOOP`t:= " Task.tick "`n")
; Helgef ---------------------------------------------
loop % count
new Task("name" A_Index)
Task.time:= ""
Task.List:= [] ;Task.List:= "" change type from Array to string if further use
msgBOX("Wait for Helgef",, "2") ;this 2 seconds is out of tick (destruction in background)
msgBOX(result.= "HELL`t:= " Task.tick "`n")
msgBOX(a,b:="",c:=""){
msgbox,,,% a, % c
}
The code has been converted from v2 to v1, if you spot a mistake in that regard please tell.
Good luck.