For 10 million elements on my system:
List creation: 0ms
List population: 432ms
List iteration: 152ms
Array creation: 196ms
Array population: 95ms
Array iteration: 95ms
ArrayList creation: 0ms
ArrayList population: 1152ms
ArrayList iteration: 99ms
List deletion/insertion: 317ms
ArrayList deletion/insertion: 231ms
List iteration: 185ms
ArrayList iteration: 99ms
List deletion/insertion: 329ms
ArrayList deletion/insertion: 227ms
List iteration: 224ms
ArrayList iteration: 101ms
Here is the code, remember to disable debugger and use C backend with optimisation enabled:
Code: Select all
#ArrayListMaxAllocationBlock = 209715200 ; 200meg
Structure ArrayListItem
nextIndex.l
prevIndex.l
EndStructure
Structure ArrayList
*buffer
sizeOfStruct.l
size.l
itemCount.l
headIndex.l
tailIndex.l
nextFreeIndex.l
Array item.ArrayListItem(1)
EndStructure
Procedure upper_power_of_two(v)
v-1
v | v >> 1
v | v >> 2
v | v >> 4
v | v >> 8
v | v >> 16
v+1
ProcedureReturn v
EndProcedure
Procedure CreateArrayList(sizeOfStruct, size.i = #Null)
*arrayList.ArrayList = AllocateStructure(ArrayList)
*arrayList\sizeOfStruct = sizeOfStruct
If *arrayList
If size
Dim *arrayList\item(size)
Else
size = 1
EndIf
*arrayList\buffer = AllocateMemory(sizeOfStruct * (size + 1), #PB_Memory_NoClear)
*arrayList\size = size
*arrayList\nextFreeIndex = 1
ProcedureReturn *arrayList
EndIf
ProcedureReturn #False
EndProcedure
Procedure AddArrayListItem(*arrayList.ArrayList, index = 0)
If Not index
index = *arrayList\tailIndex
EndIf
If index < 0 Or index > *arrayList\size Or (index <> *arrayList\headIndex And Not *arrayList\item(index)\prevIndex)
ProcedureReturn -1
EndIf
If *arrayList\nextFreeIndex > *arrayList\size
newSize = upper_power_of_two(*arrayList\size + 1)
If ((*arrayList\sizeOfStruct * (newSize + 1)) - (*arrayList\sizeOfStruct * (*arrayList\size + 1))) > #ArrayListMaxAllocationBlock
newSize = *arrayList\size + Round(#ArrayListMaxAllocationBlock / *arrayList\sizeOfStruct, #PB_Round_Up)
EndIf
ReDim *arrayList\item(newSize)
*arrayList\buffer = ReAllocateMemory(*arrayList\buffer, *arrayList\sizeOfStruct * (newSize + 1), #PB_Memory_NoClear)
*arrayList\size = newSize
EndIf
If Not *arrayList\item(*arrayList\nextFreeIndex)\nextIndex
*arrayList\item(*arrayList\nextFreeIndex)\nextIndex = *arrayList\nextFreeIndex + 1
EndIf
newIndex = *arrayList\nextFreeIndex
*arrayList\nextFreeIndex = *arrayList\item(*arrayList\nextFreeIndex)\nextIndex
FillMemory(*arrayList\buffer + (newIndex * *arrayList\sizeOfStruct), *arrayList\sizeOfStruct)
If Not *arrayList\headIndex
*arrayList\headIndex = newIndex
Else
*arrayList\item(newIndex)\prevIndex = index
EndIf
*arrayList\item(newIndex)\nextIndex = #Null
If index And *arrayList\item(index)\nextIndex
*arrayList\item(*arrayList\item(index)\nextIndex)\prevIndex = newIndex
*arrayList\item(newIndex)\nextIndex = *arrayList\item(index)\nextIndex
Else
*arrayList\tailIndex = newIndex
EndIf
If index
*arrayList\item(index)\nextIndex = newIndex
EndIf
*arrayList\itemCount + 1
ProcedureReturn newIndex
EndProcedure
Procedure RemoveArrayListItem(*arrayList.ArrayList, index = 0)
If Not index
index = *arrayList\tailIndex
EndIf
If Not *arrayList\headIndex Or index < 0 Or index > *arrayList\size Or (index <> *arrayList\headIndex And Not *arrayList\item(index)\prevIndex)
ProcedureReturn -1
EndIf
If index = *arrayList\headIndex
*arrayList\headIndex = *arrayList\item(index)\nextIndex
*arrayList\item(*arrayList\item(index)\nextIndex)\prevIndex = #Null
If index = *arrayList\tailIndex
*arrayList\headIndex = #Null
*arrayList\tailIndex = #Null
EndIf
ElseIf index = *arrayList\tailIndex
*arrayList\tailIndex = *arrayList\item(index)\prevIndex
*arrayList\item(*arrayList\item(index)\prevIndex)\nextIndex = #Null
Else
*arrayList\item(*arrayList\item(index)\prevIndex)\nextIndex = *arrayList\item(index)\nextIndex
*arrayList\item(*arrayList\item(index)\nextIndex)\prevIndex = *arrayList\item(index)\prevIndex
EndIf
prevIndex = *arrayList\item(index)\prevIndex
*arrayList\item(index)\prevIndex = #Null
*arrayList\item(index)\nextIndex = *arrayList\nextFreeIndex
*arrayList\nextFreeIndex = index
*arrayList\itemCount - 1
ProcedureReturn prevIndex
EndProcedure
Structure test
value.i
x.l
y.l
width.l
height.l
idealWidth.l
idealHeight.l
minWidth.l
minHeight.l
maxWidth.l
maxHeight.l
flags.b
topMargin.w
leftMargin.w
bottomMargin.w
rightMargin.w
*widget.Widget
*bucketAdress.Integer
*nextBucketItem
*nextFreeBucketItem.Integer
EndStructure
Structure Item
index.test[0]
EndStructure
Structure Buffer
*buffer.Item
EndStructure
OpenConsole()
maxSize = 10000000
;- List test
startTime = ElapsedMilliseconds()
NewList test.test()
endTime = ElapsedMilliseconds()
PrintN("List creation: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
For n = 1 To maxSize
AddElement(test())
*test.test = test()
*test\value = n
Next
endTime = ElapsedMilliseconds()
PrintN("List population: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
ForEach test()
*test.test = test()
*test\value / 2
Next
endTime = ElapsedMilliseconds()
PrintN("List iteration: " + Str(endTime - startTime) + "ms")
PrintN("")
;- Array test
startTime = ElapsedMilliseconds()
Dim test2.test(maxSize)
endTime = ElapsedMilliseconds()
PrintN("Array creation: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
For n = 1 To maxSize
*test.test = test2(n)
*test\value = n
Next
endTime = ElapsedMilliseconds()
PrintN("Array population: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
For n = 1 To maxSize
*test.test = test2(n)
*test\value / 2
Next
endTime = ElapsedMilliseconds()
PrintN("Array iteration: " + Str(endTime - startTime) + "ms")
PrintN("")
;- ArrayList test
startTime = ElapsedMilliseconds()
*arrayList.ArrayList = CreateArrayList(SizeOf(test))
*item.Buffer = *arrayList
endTime = ElapsedMilliseconds()
PrintN("ArrayList creation: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
For n = 1 To maxSize
i = AddArrayListItem(*arrayList)
*test.test = *item\buffer\index[i]
*test\value = n
Next
endTime = ElapsedMilliseconds()
PrintN("ArrayList population: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
i = *arrayList\headIndex
While i
*test.test = *item\buffer\index[i]
*test\value / 2
i = *arrayList\item(i)\nextIndex
Wend
endTime = ElapsedMilliseconds()
PrintN("ArrayList iteration: " + Str(endTime - startTime) + "ms")
PrintN("")
;- List + ArrayList insertion/deletion tests
RandomSeed(1337)
startTime = ElapsedMilliseconds()
ForEach test()
If Random(2) = 0
DeleteElement(test())
EndIf
If Random(2) = 0
AddElement(test())
*test.test = test()
*test\value = 255;Random(255)
EndIf
Next
endTime = ElapsedMilliseconds()
PrintN("List deletion/insertion: " + Str(endTime - startTime) + "ms")
RandomSeed(1337)
startTime = ElapsedMilliseconds()
i = *arrayList\headIndex
While i
If Random(2) = 0
i = RemoveArrayListItem(*arrayList, i)
EndIf
If Random(2) = 0
i = AddArrayListItem(*arrayList, i)
*test.test = *item\buffer\index[i]
*test\value = 255;Random(255)
EndIf
i = *arrayList\item(i)\nextIndex
Wend
endTime = ElapsedMilliseconds()
PrintN("ArrayList deletion/insertion: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
ForEach test()
*test.test = test()
*test\value / 2
Next
endTime = ElapsedMilliseconds()
PrintN("List iteration: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
i = *arrayList\headIndex
While i
*test.test = *item\buffer\index[i]
*test\value / 2
i = *arrayList\item(i)\nextIndex
Wend
endTime = ElapsedMilliseconds()
PrintN("ArrayList iteration: " + Str(endTime - startTime) + "ms")
PrintN("")
RandomSeed(1337)
startTime = ElapsedMilliseconds()
ForEach test()
If Random(2) = 0
DeleteElement(test())
EndIf
If Random(2) = 0
AddElement(test())
*test.test = test()
*test\value = 255;Random(255)
EndIf
Next
endTime = ElapsedMilliseconds()
PrintN("List deletion/insertion: " + Str(endTime - startTime) + "ms")
RandomSeed(1337)
startTime = ElapsedMilliseconds()
i = *arrayList\headIndex
While i
If Random(2) = 0
i = RemoveArrayListItem(*arrayList, i)
EndIf
If Random(2) = 0
i = AddArrayListItem(*arrayList, i)
*test.test = *item\buffer\index[i]
*test\value = 255;Random(255)
EndIf
i = *arrayList\item(i)\nextIndex
Wend
endTime = ElapsedMilliseconds()
PrintN("ArrayList deletion/insertion: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
ForEach test()
*test.test = test()
*test\value / 2
Next
endTime = ElapsedMilliseconds()
PrintN("List iteration: " + Str(endTime - startTime) + "ms")
startTime = ElapsedMilliseconds()
i = *arrayList\headIndex
While i
*test.test = *item\buffer\index[i]
*test\value / 2
i = *arrayList\item(i)\nextIndex
Wend
endTime = ElapsedMilliseconds()
PrintN("ArrayList iteration: " + Str(endTime - startTime) + "ms")
; FirstElement(test())
;
; startTime = ElapsedMilliseconds()
; i = *arrayList\headIndex
; While i
;
; *test.test = *item\buffer\index[i]
;
; *test2.test = test()
; Debug Str(*test\value) + " <-> " + Str(*test2\value)
;
; i = *arrayList\item(i)\nextIndex
; NextElement(test())
;
; Wend
; endTime = ElapsedMilliseconds()
;
; PrintN("ArrayList iteration: " + Str(endTime - startTime) + "ms")
Input()