Giả sử muốn tạo 1 List integer:
array = list(range(1000000))
Bạn đoán Python sẽ dùng bao nhiêu memory để lưu “đồng chí” array kia? Hmm… Ở đại học ta được học integer là 4 bytes, vậy tính ra với một triệu phần tử thì sẽ ~4MiB?
Trong thực tế, Python tốn ~36MiB để lưu array và các số integer này. Sử dụng memory_profiler để profile memory usage của code.
Line # Mem usage Increment Line Contents
================================================
1 37.586 MiB 37.586 MiB @profile
2 def test_list():
3 74.184 MiB 36.598 MiB array = list(range(1000000))
Tại sao?
Trong Python, mọi thứ đều là object vì thế mà sẽ tốn thêm 1 lượng bytes cho overhead memory.
In [1]: number = 1; number.__dir__()
Out[1]:
['__repr__',
'__hash__',
'__getattribute__',
'__lt__',
'__le__',
'__eq__',
'__ne__',
'__gt__',
...]
In [2]: number.__sizeof__()
Out[2]: 28
Oh, 28 bytes. Quay về với ví dụ ban đầu, sẽ là ~28MiB cho 1 triệu số integer. Vậy còn ~8MiB nữa đi đâu? ~8MiB đó thuộc về object ARRAY. List trong python là 1 mảng các pointer (con trỏ) trỏ tới bất kỳ object nào. Với ví dụ của chúng ta sẽ là 1 triệu pointers. Trong hệ điều hành 64-bit, con trỏ chiếm 8 bytes.
In [3]: arr.__sizeof__()
Out[3]: 8000040
Khác với kiểu list, numpy array không lưu reference tới bất kỳ Python object nào mà thay vào đó chỉ lưu các số mà thôi.
import numpy as np
arr = np.zeros((1000000,), dtype=np.uint32)
for i in range(1000000):
arr[i] = i
ta được kết quả như sau:
Line # Mem usage Increment Line Contents
================================================
8 37.711 MiB 37.711 MiB @profile
9 def test_numpy():
10 50.414 MiB 12.703 MiB import numpy as np
11
12 50.414 MiB 0.000 MiB arr = np.zeros((1000000,), dtype=np.uint32)
13 54.586 MiB 0.000 MiB for i in range(1000000):
14 54.586 MiB 0.562 MiB arr[i] = i
Vậy là chỉ tốn 4MiB cho array, giống như đã được dạy ở trên đại học
Sự chênh lệch giữa 4MiB và 36MiB có thể là không lớn và ta có thể sống vui vẻ, nhưng giữa 4GiB và 36GiB lại là một chuyện rất lớn.
You need to login in order to like this post: click here
YOU MIGHT ALSO LIKE