我知道shift,push和pop是用於添加/刪除數組元素的Array方法,但我不確定內存中實際發生了什麼。舉例來說,刪除數組的最後一個元素的方法pop。它讓我想起堆棧中使用的LIFO命令,但是我認爲這個元素並沒有像彙編編程那樣真正「彈出」而是整個數組的索引被移位。我真的不知道,如果有人能幫助我,我會很感激。Ruby:內存中的Shift,Push和Pop
0
A
回答
5
Ruby適用於那些患有這種想法的程序員。我們相信那些執行這些程序的人可以在優化性能和內存管理方面做得最好。
如果你只是好奇,這裏是在Rubinius的陣列#移位代碼:
def shift(n=undefined)
Rubinius.check_frozen
if n.equal? undefined
return nil if @total == 0
obj = @tuple.at @start
@tuple.put @start, nil
@start += 1
@total -= 1
obj
else
n = Rubinius::Type.coerce_to(n, Fixnum, :to_int)
raise ArgumentError, "negative array size" if n < 0
slice!(0, n)
end
end
而且你可以看到,一個陣列本身就是一個Rubinius的元組::,並在元組的定義,它是Rubinius :: Array。它所做的只是將開始位置放到下一個位置。我不確定他們會釋放它使用的空間(我認爲它會這樣),因爲你必須深入挖掘。
在官方1.9.3中,我不知道它是如何實現的,因爲它們在C中執行,而且它們很難閱讀。如果你想知道更多的細節,你可以在GitHub上發佈Rubinius,或者從ruby-lang.org上下載官方的1.9.3,並閱讀源代碼。您可以瞭解更多關於C/C++編程太:)
於是我趕緊通過官方1.9.3的代碼去了,這是數組#轉換功能定義:
static VALUE
rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
{
VALUE result;
long n;
if (argc == 0) {
return rb_ary_shift(ary);
}
rb_ary_modify_check(ary);
result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
n = RARRAY_LEN(result);
if (ARY_SHARED_P(ary)) {
if (ARY_SHARED_NUM(ARY_SHARED(ary)) == 1) {
rb_mem_clear(RARRAY_PTR(ary), n);
}
ARY_INCREASE_PTR(ary, n);
}
else {
MEMMOVE(RARRAY_PTR(ary), RARRAY_PTR(ary)+n, VALUE, RARRAY_LEN(ary)-n);
}
ARY_INCREASE_LEN(ary, -n);
return result;
}
這line:
MEMMOVE(RARRAY_PTR(ary), RARRAY_PTR(ary)+n, VALUE, RARRAY_LEN(ary)-n);
它告訴我們它實際上移動的內存塊偏移n。這可能就是爲什麼這位官員比魯比尼烏斯慢的原因......魯比尼烏斯在大型記憶中佔據優勢,但是可以節省時間;官方消耗更少的內存,但需要更多的時間...
相關問題
- 1. Clojure的:pop和push
- 2. Pop和Push ViewController的區別
- 3. 解釋Push和Pop Loop
- 4. WPF Push and Pop
- 5. 組裝x86中的PUSH和POP出DWORD
- 6. 堆棧中的push和pop矩陣(openGL)
- 7. ARMv5彙編中的PUSH/POP
- 8. 的Javascript SHIFT和POP的關聯數組
- 9. 如何在Scheme中編寫Push和Pop?
- 10. 瞭解heapq push pop
- 11. MongoDB的模式結構 - push和pop
- 12. 使用push和pop的堆棧
- 13. 如何使用push和pop來交換2個寄存器的內容?
- 14. push和pop增加現場字節
- 15. 寫作pop和push功能疊加
- 16. Big Oh not notation - push and pop
- 17. Firebase pop()與push()相反嗎?
- 18. Push/pop當前數據庫
- 19. 在鏈表中實現push/pop(C++)
- 20. Ruby中的'pop'方法
- 21. 3D Peek和Pop內存泄漏
- 22. python中單向鏈表上的Push和Pop方法
- 23. Python中的單鏈表,如何編寫pop和push?
- 24. 如何正確PUSH/POP的元素內記錄的陣列ImmutableJS
- 25. pop()隊列中的內存浪費
- 26. 定製push和pop動畫的iOS 7和8
- 27. (C++)無法從堆棧對象中調用push()和pop()
- 28. KnockoutJS - UI不會使用內置的observableArray方法更新,除了push和pop
- 29. PUSH/POP - 視圖 - 控制器EXC_BAD_ACCESS
- 30. 使用push和pop導航行爲重用相同的視圖
虐待檢查c源代碼。我很好奇。 – 2012-04-21 03:42:07
@BhubhuHbuhdbus稍微更新:)我也經歷了C代碼。 – texasbruce 2012-04-21 03:59:41