我預計Array#shift
和Array#unshift
的運行時間都是Θ(n)
。原因是機器需要遍歷每個陣列成員並將其分配給左側或右側的鍵。運行時間Array#unshift vs Array#shift
在Array#unshift
的情況下,假設只有一個值作爲參數傳入並且存在大量數組成員,我假定array[0]
的值賦值對運行時間沒有顯着影響。換句話說,當數組成員數很多,並且傳入Array#unshift
的變量數很低時,我預計Array#shift
和Array#unshift
具有相同的運行時間。
在Ruby 2.1.2上運行基準測試時,這些假設並不適用。爲什麼?
代碼:
require 'benchmark'
GC.disable
number_of_elements = 25_600_000
a1 =[]
a2 = []
a3 = []
a4 = []
q1 = Queue.new
q2 = Queue.new
puts number_of_elements
number_of_elements.times do
q1.enq(true)
q2.enq(true)
a1 << true
a2 << true
a3 << true
a4 << true
end
number_of_operations = 1
Benchmark.bm do |bm|
puts "Queue#enq('test')"
bm.report do
number_of_operations.times { q1.enq('test') }
end
puts "Queue#deq"
bm.report do
number_of_operations.times { q2.deq }
end
puts "Array#shift"
bm.report do
number_of_operations.times { a1.shift }
end
puts "Array#unshift"
bm.report do
number_of_operations.times { a2.unshift('test') }
end
puts "Array#pop"
bm.report do
number_of_operations.times { a3.pop }
end
puts "Array#<<"
bm.report do
number_of_operations.times { a4 << 'test' }
end
end
結果:
25600000
user system total real
Queue#enq('test')
0.000000 0.000000 0.000000 ( 0.000006)
Queue#deq
0.010000 0.020000 0.030000 ( 0.029928)
Array#shift
0.010000 0.020000 0.030000 ( 0.032203)
Array#unshift
0.080000 0.060000 0.140000 ( 0.143272)
Array#pop
0.000000 0.000000 0.000000 ( 0.000004)
Array#<<
0.000000 0.000000 0.000000 ( 0.000007)
如果您提高操作次數,會發生什麼情況? – Ajedi32
#[email protected]:0.016307,#[email protected]:0.059878,#shift @ 64m:0.098583,#shift @ 128m:0.344900。 #[email protected]:0.059736,#[email protected]:0.126382,#unshift @ 64m:0.285351,#unshift @ 128m:0.993967。通過只比較這些比率,似乎#shift運行在Θ(3.4n)和#unshift稍微指數。 – migu
您是否研究過Ruby源代碼以理解數組是如何實現的以及如何使'shift' /'unshift'工作?幕後會出現各種各樣的事情,這些事情會掩蓋你的結果。將一個元素添加到數組的開始處並不一定會爲數組分配一個新條目,它可能會分配多個條目,或者它可能只是移動一個數組 - 開始 - 指針指針;同樣,移動元素可能只是更新一個指向新索引0地址的指針。 –