Refactored test and benchmark, extended README, added clear and clearPop methods, added equality operator, reversedPairs iterator and extend procedures
This commit is contained in:
parent
35956f1464
commit
1c6aa863eb
35
README.md
35
README.md
|
@ -11,7 +11,7 @@ beginning is an O(n) operation).
|
||||||
|
|
||||||
### LinkedDeque
|
### LinkedDeque
|
||||||
|
|
||||||
A `LinkedDeque` is a deque based on a doubly linked list
|
A `LinkedDeque` is a deque based on a doubly linked list.
|
||||||
|
|
||||||
```nim
|
```nim
|
||||||
import nimdeque
|
import nimdeque
|
||||||
|
@ -30,10 +30,15 @@ queue.addLeft(-1)
|
||||||
queue.addLeft(-2)
|
queue.addLeft(-2)
|
||||||
|
|
||||||
# Pops the first element in O(1) time
|
# Pops the first element in O(1) time
|
||||||
queue.pop(0)
|
queue.pop()
|
||||||
|
|
||||||
# Pops the last element in O(1) time
|
# Pops the last element in O(1) time
|
||||||
queue.pop(queue.high())
|
queue.pop(queue.high())
|
||||||
|
# This can also be written as
|
||||||
|
queue.pop(^1)
|
||||||
|
|
||||||
|
# Pops element at position n
|
||||||
|
queue.pop(n)
|
||||||
|
|
||||||
# Supports iteration
|
# Supports iteration
|
||||||
for i, e in queue:
|
for i, e in queue:
|
||||||
|
@ -54,8 +59,32 @@ echo 0 in queue # true
|
||||||
assert queue[0] == -1
|
assert queue[0] == -1
|
||||||
assert queue[^1] == queue[queue.high()]
|
assert queue[^1] == queue[queue.high()]
|
||||||
|
|
||||||
|
# It's possible to extend a deque with other deques or with seqs
|
||||||
|
# of compatible type
|
||||||
|
var other = newLinkedDeque[int]()
|
||||||
|
other.add(9)
|
||||||
|
other.add(10)
|
||||||
|
queue.extend(@[5, 6, 7, 8])
|
||||||
|
queue.extend(other)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
## Notes
|
||||||
|
|
||||||
__Note__: This is mostly a toy, there are no performance guarantees nor particular optimizations other than very obvious ones. With
|
- All queue constructors take an optional `maxSize` argument which limits the size of the queue. The
|
||||||
|
default value is 0 (no size limit). When `maxSize > 0`, the queue will discard elements from the head when
|
||||||
|
items are added at the end and conversely pop items at the end when one is added at the head. Calling `insert`
|
||||||
|
on a full queue will raise an `IndexDefect`
|
||||||
|
- Two deques compare equal if they have the same elements inside them, in the same order. The value of `maxSize` is
|
||||||
|
disregarded in comparisons
|
||||||
|
- Calls to `extend()` **do not** raise any errors when the queue is full. They're merely an abstraction over a for
|
||||||
|
loop calling `self.add()` with every item from the other iterable
|
||||||
|
- Deques in this module do not support slicing. Use the built-in `seq` type if you need fast random accessing and/or slicing
|
||||||
|
capabilities
|
||||||
|
- The objects in this module are **all** tracked references! (Unlike the `std/deques` module which implements them as value
|
||||||
|
types and gives `var` variants of each procedure)
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
This is mostly a toy, there are no performance guarantees nor particular optimizations other than very obvious ones. With
|
||||||
that said, the collections _do_ work and are tested somewhat thoroughly (please report any bugs!)
|
that said, the collections _do_ work and are tested somewhat thoroughly (please report any bugs!)
|
||||||
|
|
|
@ -29,4 +29,8 @@ export `[]`
|
||||||
export `[]=`
|
export `[]=`
|
||||||
export pairs
|
export pairs
|
||||||
export linked.`$`
|
export linked.`$`
|
||||||
export insert
|
export insert
|
||||||
|
export extend
|
||||||
|
export reversedPairs
|
||||||
|
export clear
|
||||||
|
export clearPop
|
|
@ -59,8 +59,6 @@ proc newLinkedDeque*[T](maxSize: int = 0): LinkedDeque[T] =
|
||||||
if maxSize < 0:
|
if maxSize < 0:
|
||||||
raise newException(ValueError, "maxSize cannot be less than zero")
|
raise newException(ValueError, "maxSize cannot be less than zero")
|
||||||
result.maxSize = maxSize
|
result.maxSize = maxSize
|
||||||
if result.maxSize == 0:
|
|
||||||
result.maxSize = int.high()
|
|
||||||
|
|
||||||
|
|
||||||
proc len*[T](self: LinkedDeque[T]): int =
|
proc len*[T](self: LinkedDeque[T]): int =
|
||||||
|
@ -162,6 +160,21 @@ proc pop*[T](self: LinkedDeque[T], pos: BackwardsIndex): T =
|
||||||
result = self.pop(self.size - int(pos))
|
result = self.pop(self.size - int(pos))
|
||||||
|
|
||||||
|
|
||||||
|
proc clear*[T](self: LinkedDeque[T]) =
|
||||||
|
## Clears the deque in constant time
|
||||||
|
## (relies on the GC to clean up!)
|
||||||
|
self.head = nil
|
||||||
|
self.tail = nil
|
||||||
|
self.size = 0
|
||||||
|
|
||||||
|
|
||||||
|
proc clearPop*[T](self: LinkedDeque[T]) =
|
||||||
|
## Clears the deque by repeatedly
|
||||||
|
## calling self.pop() in O(n) time
|
||||||
|
while self.len() > 0:
|
||||||
|
discard self.pop()
|
||||||
|
|
||||||
|
|
||||||
proc add*[T](self: LinkedDeque[T], val: T) =
|
proc add*[T](self: LinkedDeque[T], val: T) =
|
||||||
## Appends an element at the end
|
## Appends an element at the end
|
||||||
## of the queue
|
## of the queue
|
||||||
|
@ -172,7 +185,7 @@ proc add*[T](self: LinkedDeque[T], val: T) =
|
||||||
self.tail = newNode
|
self.tail = newNode
|
||||||
if self.head == nil:
|
if self.head == nil:
|
||||||
self.head = newNode
|
self.head = newNode
|
||||||
elif self.size == self.maxSize:
|
elif self.maxSize > 0 and self.size == self.maxSize:
|
||||||
discard self.pop()
|
discard self.pop()
|
||||||
inc(self.size)
|
inc(self.size)
|
||||||
|
|
||||||
|
@ -184,11 +197,12 @@ proc addLeft*[T](self: LinkedDeque[T], val: T) =
|
||||||
## takes constant time
|
## takes constant time
|
||||||
var node = newDequeNode(val)
|
var node = newDequeNode(val)
|
||||||
var head = self.head
|
var head = self.head
|
||||||
if self.size == self.maxSize:
|
if self.maxSize > 0 and self.size == self.maxSize:
|
||||||
discard self.pop(self.high())
|
discard self.pop(self.high())
|
||||||
self.head = node
|
self.head = node
|
||||||
self.head.next = head
|
self.head.next = head
|
||||||
head.prev = node
|
if head != nil:
|
||||||
|
head.prev = node
|
||||||
inc(self.size)
|
inc(self.size)
|
||||||
|
|
||||||
|
|
||||||
|
@ -199,12 +213,12 @@ proc insert*[T](self: LinkedDeque[T], pos: int, val: T) =
|
||||||
## respectively. In all other cases, all items
|
## respectively. In all other cases, all items
|
||||||
## are "shifted" by 1 (shifted is in quotes because
|
## are "shifted" by 1 (shifted is in quotes because
|
||||||
## no shifting actually occurs, but the result is
|
## no shifting actually occurs, but the result is
|
||||||
## the same). The operation takes roughly constant
|
## the same). The operation takes constant time at
|
||||||
## time and the complexity becomes O(n) the closer
|
## the ends, but the complexity grows to O(n) the closer
|
||||||
## the index gets to the middle of the deque. This
|
## the index gets to the middle of the deque. This
|
||||||
## proc raises an IndexDefect if the queue's max
|
## proc raises an IndexDefect if the queue's max
|
||||||
## size is reached
|
## size is reached
|
||||||
if self.size == self.maxSize:
|
if self.maxSize > 0 and self.size == self.maxSize:
|
||||||
raise newException(IndexDefect, &"LinkedDeque has reached its maximum size ({self.maxSize})")
|
raise newException(IndexDefect, &"LinkedDeque has reached its maximum size ({self.maxSize})")
|
||||||
if pos == 0:
|
if pos == 0:
|
||||||
self.addLeft(val)
|
self.addLeft(val)
|
||||||
|
@ -250,6 +264,24 @@ iterator reversed*[T](self: LinkedDeque[T]): T =
|
||||||
node = node.prev
|
node = node.prev
|
||||||
|
|
||||||
|
|
||||||
|
iterator reversedPairs*[T](self: LinkedDeque[T]): auto =
|
||||||
|
## Implements pairwise reversed iteration
|
||||||
|
var i = 0
|
||||||
|
for e in self.reversed():
|
||||||
|
yield (i, e)
|
||||||
|
inc(i)
|
||||||
|
|
||||||
|
|
||||||
|
proc `==`*[T](self: LinkedDeque[T], other: LinkedDeque[T]): bool =
|
||||||
|
## Compares two LinkedDeque objects
|
||||||
|
if self.high() != other.high():
|
||||||
|
return false
|
||||||
|
for i, item in self:
|
||||||
|
if item != other[i]:
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
proc contains*[T](self: LinkedDeque[T], val: T): bool =
|
proc contains*[T](self: LinkedDeque[T], val: T): bool =
|
||||||
## Returns if the given element is in
|
## Returns if the given element is in
|
||||||
## the deque
|
## the deque
|
||||||
|
@ -259,6 +291,18 @@ proc contains*[T](self: LinkedDeque[T], val: T): bool =
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
proc extend*[T](self: LinkedDeque[T], other: LinkedDeque[T]) =
|
||||||
|
## Extends self with the items from other
|
||||||
|
for item in other:
|
||||||
|
self.add(item)
|
||||||
|
|
||||||
|
|
||||||
|
proc extend*[T](self: LinkedDeque[T], other: seq[T]) =
|
||||||
|
## Extends self with the items from other
|
||||||
|
for item in other:
|
||||||
|
self.add(item)
|
||||||
|
|
||||||
|
|
||||||
proc `$`*[T](self: LinkedDeque[T]): string =
|
proc `$`*[T](self: LinkedDeque[T]): string =
|
||||||
## Returns a string representation
|
## Returns a string representation
|
||||||
## of the deque
|
## of the deque
|
||||||
|
|
235
tests/linked.nim
235
tests/linked.nim
|
@ -11,123 +11,258 @@
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
import stats
|
||||||
|
import times
|
||||||
import random
|
import random
|
||||||
import strformat
|
import strformat
|
||||||
import ../src/nimdeque
|
import ../src/nimdeque
|
||||||
|
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
const size = 1000
|
const size = 1500
|
||||||
|
const benchSize = 150000
|
||||||
|
|
||||||
|
echo &"Running tests with queue of size {size}"
|
||||||
var deque = newLinkedDeque[int]()
|
var deque = newLinkedDeque[int]()
|
||||||
echo &"Generating {size} values"
|
var testStart = cpuTime()
|
||||||
|
echo &"\t- Checking add()"
|
||||||
for i in countup(0, size - 1, 1):
|
for i in countup(0, size - 1, 1):
|
||||||
deque.add(i)
|
deque.add(i)
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert deque.len() == size
|
doAssert deque.len() == size
|
||||||
echo "Checking iteration"
|
|
||||||
echo "\t- Checking indeces"
|
echo "\t- Checking iteration"
|
||||||
for i in countup(0, size - 1, 1):
|
for i in countup(0, size - 1, 1):
|
||||||
doAssert deque[i] == i
|
doAssert deque[i] == i
|
||||||
echo "\t- Checking pairs"
|
|
||||||
for i, e in deque:
|
for i, e in deque:
|
||||||
assert i == e
|
doAssert i == e
|
||||||
echo "\t- Checking reversed iteration"
|
|
||||||
var j = 0
|
var j = 0
|
||||||
for e in deque.reversed():
|
for e in deque.reversed():
|
||||||
assert size - j - 1 == e
|
doAssert size - j - 1 == e
|
||||||
inc(j)
|
inc(j)
|
||||||
echo "Checking contains"
|
for i, e in deque.reversedPairs():
|
||||||
|
doAssert size - i - 1 == e
|
||||||
|
|
||||||
|
echo "\t- Checking contains()"
|
||||||
for i in countup(0, size - 1, 1):
|
for i in countup(0, size - 1, 1):
|
||||||
doAssert i in deque
|
doAssert i in deque
|
||||||
echo "Popping off the head"
|
doAssert 48574857 notin deque
|
||||||
|
doAssert -0xfffffff notin deque
|
||||||
|
echo "\t- Checking pop(0)"
|
||||||
doAssert deque.pop() == 0
|
doAssert deque.pop() == 0
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert deque.len() == size - 1
|
doAssert deque.len() == size - 1
|
||||||
echo "\t- Checking new head"
|
|
||||||
doAssert deque[0] == 1
|
doAssert deque[0] == 1
|
||||||
echo "Popping off the tail"
|
|
||||||
|
echo "\t- Checking pop(^1)"
|
||||||
doAssert deque.pop(deque.high()) == size - 1
|
doAssert deque.pop(deque.high()) == size - 1
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert deque.len() == size - 2
|
doAssert deque.len() == size - 2
|
||||||
echo "\t- Checking new tail"
|
|
||||||
doAssert deque[deque.high()] == size - 2
|
doAssert deque[deque.high()] == size - 2
|
||||||
echo "Re-checking values"
|
|
||||||
|
echo "\t- Re-checking values"
|
||||||
for i in countup(0, size - 3, 1):
|
for i in countup(0, size - 3, 1):
|
||||||
doAssert deque[i] == i + 1
|
doAssert deque[i] == i + 1
|
||||||
echo "Checking addLeft"
|
|
||||||
|
echo "\t- Checking addLeft()"
|
||||||
deque.addLeft(0)
|
deque.addLeft(0)
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert deque.len() == size - 1
|
doAssert deque.len() == size - 1
|
||||||
echo "\t- Re-checking head"
|
|
||||||
doAssert deque[0] == 0
|
doAssert deque[0] == 0
|
||||||
echo "Re-checking values"
|
|
||||||
for i in countup(0, size - 2, 1):
|
for i in countup(0, size - 2, 1):
|
||||||
doAssert deque[i] == i
|
doAssert deque[i] == i
|
||||||
echo "Checking insert(3)"
|
|
||||||
|
echo "\t- Checking insert(3)"
|
||||||
var oldLen = deque.len()
|
var oldLen = deque.len()
|
||||||
deque.insert(3, 69420)
|
deque.insert(3, 69420)
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert oldLen + 1 == deque.len()
|
doAssert oldLen + 1 == deque.len()
|
||||||
echo "\t- Checking inserted value"
|
|
||||||
doAssert deque.pop(3) == 69420
|
doAssert deque.pop(3) == 69420
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert deque.len() == oldLen
|
doAssert deque.len() == oldLen
|
||||||
echo &"Checking insert({size - 2})"
|
|
||||||
|
echo &"\t- Checking insert({size - 2})"
|
||||||
oldLen = deque.len()
|
oldLen = deque.len()
|
||||||
deque.insert(size - 2, 0x42362)
|
deque.insert(size - 2, 0x42362)
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert oldLen + 1 == deque.len()
|
doAssert oldLen + 1 == deque.len()
|
||||||
echo "\t- Checking inserted value"
|
|
||||||
doAssert deque.pop(size - 1) == 0x42362
|
doAssert deque.pop(size - 1) == 0x42362
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert deque.len() == oldLen
|
doAssert deque.len() == oldLen
|
||||||
echo &"Checking insert({size div 2})"
|
|
||||||
|
echo &"\t- Checking insert({size div 2})"
|
||||||
oldLen = deque.len()
|
oldLen = deque.len()
|
||||||
deque.insert(size div 2, 0xf7102)
|
deque.insert(size div 2, 0xf7102)
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert oldLen + 1 == deque.len()
|
doAssert oldLen + 1 == deque.len()
|
||||||
echo "\t- Checking inserted value"
|
|
||||||
doAssert deque.pop(size div 2) == 0xf7102
|
doAssert deque.pop(size div 2) == 0xf7102
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert deque.len() == oldLen
|
doAssert deque.len() == oldLen
|
||||||
|
|
||||||
randomize()
|
randomize()
|
||||||
let idx = rand(size - 1)
|
let idx = rand(size - 1)
|
||||||
echo &"Checking insert({idx})"
|
echo &"\t- Checking insert({idx})"
|
||||||
oldLen = deque.len()
|
oldLen = deque.len()
|
||||||
deque.insert(size - 2, idx)
|
deque.insert(size - 2, idx)
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert oldLen + 1 == deque.len()
|
doAssert oldLen + 1 == deque.len()
|
||||||
echo "\t- Checking inserted value"
|
|
||||||
doAssert deque.pop(size - 1) == idx
|
doAssert deque.pop(size - 1) == idx
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert deque.len() == oldLen
|
doAssert deque.len() == oldLen
|
||||||
echo "Checking backwards indeces"
|
|
||||||
|
echo "\t- Checking backwards indeces"
|
||||||
for i in countdown(deque.high(), 1):
|
for i in countdown(deque.high(), 1):
|
||||||
doAssert deque[^i] == deque[deque.len() - i]
|
doAssert deque[^i] == deque[deque.len() - i]
|
||||||
deque.add(deque.pop(^1))
|
deque.add(deque.pop(^1))
|
||||||
doAssert deque[deque.high()] == deque[^1]
|
doAssert deque[deque.high()] == deque[^1]
|
||||||
echo &"Checking maxSize ({size div 2})"
|
|
||||||
|
echo &"\t- Checking queue with maxSize {size div 2}"
|
||||||
var queue = newLinkedDeque[int](size div 2)
|
var queue = newLinkedDeque[int](size div 2)
|
||||||
echo &"\t- Generating {size div 2} values"
|
|
||||||
for i in countup(0, (size div 2) - 1):
|
for i in countup(0, (size div 2) - 1):
|
||||||
queue.add(i)
|
queue.add(i)
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert queue.len() == size div 2
|
doAssert queue.len() == size div 2
|
||||||
var temp = queue[0]
|
var temp = queue[0]
|
||||||
echo "\t- Testing append at the end"
|
|
||||||
queue.add((size div 2) + 1)
|
queue.add((size div 2) + 1)
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert queue.len() == size div 2
|
doAssert queue.len() == size div 2
|
||||||
echo "\t- Checking item"
|
|
||||||
doAssert queue[^1] == (size div 2) + 1
|
doAssert queue[^1] == (size div 2) + 1
|
||||||
echo "\t- Checking displacement"
|
|
||||||
doAssert queue[0] == temp + 1
|
doAssert queue[0] == temp + 1
|
||||||
echo "Testing prepend at the beginning"
|
|
||||||
queue.addLeft(0)
|
queue.addLeft(0)
|
||||||
echo "\t- Checking length"
|
|
||||||
doAssert queue.len() == size div 2
|
doAssert queue.len() == size div 2
|
||||||
echo "\t- Checking item"
|
|
||||||
doAssert queue[0] == 0
|
doAssert queue[0] == 0
|
||||||
echo "\t- Checking displacement"
|
|
||||||
doAssert queue[^1] == (size div 2) - 1
|
doAssert queue[^1] == (size div 2) - 1
|
||||||
echo "All tests passed!"
|
|
||||||
|
echo "\t- Testing extend()"
|
||||||
|
var old = deque.len()
|
||||||
|
var s = @[1, 2, 3, 4, 5, 6]
|
||||||
|
deque.extend(s)
|
||||||
|
for i in countup(size + 5, deque.high()):
|
||||||
|
doAssert deque[i] == s[i]
|
||||||
|
doAssert old + len(s) == deque.len()
|
||||||
|
|
||||||
|
echo "\t- Testing clear()"
|
||||||
|
deque.clear()
|
||||||
|
doAssert deque.len() == 0
|
||||||
|
doAssertRaises(IndexDefect, echo deque[0])
|
||||||
|
echo &"Tests completed in {cpuTime() - testStart} seconds"
|
||||||
|
|
||||||
|
## End of tests, start of benchmark
|
||||||
|
echo &"\nRunning benchmarks with queue size of {benchSize} against a seq"
|
||||||
|
var q = newLinkedDeque[int]()
|
||||||
|
var q2: seq[int] = @[]
|
||||||
|
var t: seq[float] = @[]
|
||||||
|
var tmp: float
|
||||||
|
var st: RunningStat
|
||||||
|
var benchStart = cpuTime()
|
||||||
|
var start = cpuTime()
|
||||||
|
echo &" Benchmarking LinkedDeque.add()"
|
||||||
|
for i in countup(0, benchSize - 1):
|
||||||
|
tmp = cpuTime()
|
||||||
|
q.add(i)
|
||||||
|
t.add(cpuTime() - tmp)
|
||||||
|
st.push(t)
|
||||||
|
echo &"""
|
||||||
|
- Done in {cpuTime() - start} seconds. Results (in seconds):
|
||||||
|
- min: {st.min}
|
||||||
|
- max: {st.max}
|
||||||
|
- avg: {st.mean()}
|
||||||
|
- stdev: {st.standardDeviation()}"""
|
||||||
|
st.clear()
|
||||||
|
t = @[]
|
||||||
|
start = cpuTime()
|
||||||
|
echo &" Benchmarking seq.add()"
|
||||||
|
for i in countup(0, benchSize - 1):
|
||||||
|
tmp = cpuTime()
|
||||||
|
q2.add(i)
|
||||||
|
t.add(cpuTime() - tmp)
|
||||||
|
st.push(t)
|
||||||
|
echo &"""
|
||||||
|
- Done in {cpuTime() - start} seconds. Results (in seconds):
|
||||||
|
- min: {st.min}
|
||||||
|
- max: {st.max}
|
||||||
|
- avg: {st.mean()}
|
||||||
|
- stdev: {st.standardDeviation()}"""
|
||||||
|
st.clear()
|
||||||
|
t = @[]
|
||||||
|
start = cpuTime()
|
||||||
|
echo &" Benchmarking LinkedDeque.pop(0)"
|
||||||
|
for i in countup(0, size * 10 - 1):
|
||||||
|
tmp = cpuTime()
|
||||||
|
discard q.pop()
|
||||||
|
t.add(cpuTime() - tmp)
|
||||||
|
st.push(t)
|
||||||
|
echo &"""
|
||||||
|
- Done in {cpuTime() - start} seconds. Results (in seconds):
|
||||||
|
- min: {st.min}
|
||||||
|
- max: {st.max}
|
||||||
|
- avg: {st.mean()}
|
||||||
|
- stdev: {st.standardDeviation()}"""
|
||||||
|
st.clear()
|
||||||
|
t = @[]
|
||||||
|
start = cpuTime()
|
||||||
|
echo &" Benchmarking seq.del(0)"
|
||||||
|
for i in countup(0, size * 10 - 1):
|
||||||
|
tmp = cpuTime()
|
||||||
|
q2.del(0)
|
||||||
|
t.add(cpuTime() - tmp)
|
||||||
|
st.push(t)
|
||||||
|
echo &"""
|
||||||
|
- Done in {cpuTime() - start} seconds. Results (in seconds):
|
||||||
|
- min: {st.min}
|
||||||
|
- max: {st.max}
|
||||||
|
- avg: {st.mean()}
|
||||||
|
- stdev: {st.standardDeviation()}"""
|
||||||
|
st.clear()
|
||||||
|
t = @[]
|
||||||
|
start = cpuTime()
|
||||||
|
q2 = @[]
|
||||||
|
echo &" Benchmarking LinkedDeque.addLeft()"
|
||||||
|
for i in countup(0, benchSize - 1):
|
||||||
|
tmp = cpuTime()
|
||||||
|
q.addLeft(i)
|
||||||
|
t.add(cpuTime() - tmp)
|
||||||
|
st.push(t)
|
||||||
|
echo &"""
|
||||||
|
- Done in {cpuTime() - start} seconds. Results (in seconds):
|
||||||
|
- min: {st.min}
|
||||||
|
- max: {st.max}
|
||||||
|
- avg: {st.mean()}
|
||||||
|
- stdev: {st.standardDeviation()}"""
|
||||||
|
st.clear()
|
||||||
|
t = @[]
|
||||||
|
start = cpuTime()
|
||||||
|
echo &" Benchmarking seq.insert(0)"
|
||||||
|
for i in countup(0, benchSize - 1):
|
||||||
|
tmp = cpuTime()
|
||||||
|
q2.insert(i, 0)
|
||||||
|
t.add(cpuTime() - tmp)
|
||||||
|
st.push(t)
|
||||||
|
echo &"""
|
||||||
|
- Done in {cpuTime() - start} seconds. Results (in seconds):
|
||||||
|
- min: {st.min}
|
||||||
|
- max: {st.max}
|
||||||
|
- avg: {st.mean()}
|
||||||
|
- stdev: {st.standardDeviation()}"""
|
||||||
|
st.clear()
|
||||||
|
t = @[]
|
||||||
|
start = cpuTime()
|
||||||
|
echo " Benchmarking random access for LinkedDeque (10000 times)"
|
||||||
|
for i in countup(0, 10000):
|
||||||
|
tmp = cpuTime()
|
||||||
|
discard q[rand(benchSize - 1)]
|
||||||
|
t.add(cpuTime() - tmp)
|
||||||
|
st.push(t)
|
||||||
|
echo &"""
|
||||||
|
- Done in {cpuTime() - start} seconds. Results (in seconds):
|
||||||
|
- min: {st.min}
|
||||||
|
- max: {st.max}
|
||||||
|
- avg: {st.mean()}
|
||||||
|
- stdev: {st.standardDeviation()}"""
|
||||||
|
st.clear()
|
||||||
|
t = @[]
|
||||||
|
echo " Benchmarking random access for seq (10000 times)"
|
||||||
|
for i in countup(0, 10000):
|
||||||
|
tmp = cpuTime()
|
||||||
|
discard q2[rand(benchSize - 1)]
|
||||||
|
t.add(cpuTime() - tmp)
|
||||||
|
st.push(t)
|
||||||
|
echo &"""
|
||||||
|
- Done in {cpuTime() - start} seconds. Results (in seconds):
|
||||||
|
- min: {st.min}
|
||||||
|
- max: {st.max}
|
||||||
|
- avg: {st.mean()}
|
||||||
|
- stdev: {st.standardDeviation()}"""
|
||||||
|
st.clear()
|
||||||
|
t = @[]
|
||||||
|
q2 = @[]
|
||||||
|
|
||||||
|
echo &"Total benchmark time: {cpuTime() - benchStart}"
|
||||||
|
echo &"Total execution time: {cpuTime() - testStart}"
|
Loading…
Reference in New Issue