程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python memory allocation Secrets

編輯:Python

Python Medium sys Modules are extremely basic and important , It mainly provides some for the interpreter to use ( Or maintained by it ) The variable of , And some functions that strongly interact with the interpreter .

This article will make frequent use of the module's getsizeof() Method , therefore , Let me briefly introduce :

  • This method is used to get the byte size of an object (bytes)
  • It only calculates the memory directly occupied , Instead of calculating the memory of the referenced object within the object

Here is an intuitive example :

import sys
a = [1, 2]
b = [a, a] # namely [[1, 2], [1, 2]]
# a、b There are only two elements , So the size of the direct occupancy is the same
sys.getsizeof(a) # result :80
sys.getsizeof(b) # result :80

The example above illustrates one thing : A statically created list , If there are only two elements , So the memory it uses is 80 byte , No matter what the element points to .

Okay , Have this measuring tool , Let's explore Python What little secrets are hidden in the built-in objects of .

1、 Empty object is not “ empty ” Of !
For some of the empty objects we are familiar with , For example, an empty string 、 An empty list 、 Empty dictionary, etc , I wonder if you have ever been curious , Have you ever thought about these problems :
Empty objects do not occupy memory ? If it takes up memory , How much does it take ? Why is it allocated like this ?

Go straight to the code , Let's take a look at the size of empty objects of several basic data structures :

import sys
sys.getsizeof("") # 49
sys.getsizeof([]) # 64
sys.getsizeof(()) # 48
sys.getsizeof(set()) # 224
sys.getsizeof(dict()) # 240
# As a reference :
sys.getsizeof(1) # 28
sys.getsizeof(True) # 28

so , Although they are all empty objects , But these objects are not in memory allocation “ empty ”, And the distribution is quite large ( Remember these numbers , I will take the exam later ).

Arrange the order : Basic figures < An empty tuple < An empty string < An empty list < Empty set < An empty dictionary .

How to explain this little secret ?

Because these empty objects are containers , We can understand in abstract : Part of their memory is used to create the skeleton of the container 、 Record container information ( Such as reference count 、 Usage information, etc )、 Some of the memory is pre allocated .

2、 Memory expansion is not uniform !
Empty object is not empty , Part of the reason is Python The interpreter allocates some initial space for them . Without exceeding the initial memory , Every time you add elements , Just use the existing memory , Thus, it avoids applying for new memory .

that , If the initial memory is allocated , How is the new memory allocated ?

import sys
letters = "abcdefghijklmnopqrstuvwxyz"
a = []
for i in letters:
a.append(i)
print(f'{len(a)}, sys.getsizeof(a) = {sys.getsizeof(a)}')
b = set()
for j in letters:
b.add(j)
print(f'{len(b)}, sys.getsizeof(b) = {sys.getsizeof(b)}')
c = dict()
for k in letters:
c[k] = k
print(f'{len(c)}, sys.getsizeof(c) = {sys.getsizeof(c)}')

Add... To three types of variable objects respectively 26 Elements , See what happens :

So we can see the secret of mutable objects when they are extended :

  • Over allocation mechanism : New memory is not allocated on demand , It's more of a distribution , So when you add a few more elements , You don't need to apply for new memory right away
  • Non uniform distribution mechanism : Three types of objects apply for new memory at different frequencies , However, the over allocated memory of the same class of objects is not even , But gradually

3、 A list is not equal to a list !
When the above mutable objects are extended , There is a similar distribution mechanism , The effect can be seen clearly in dynamic capacity expansion .

that , Is there such an allocation mechanism for statically created objects ? It's the dynamic expansion ratio , Is there a difference ?

First look at the collection and Dictionary :

# Create objects statically
set_1 = {1, 2, 3, 4}
set_2 = {1, 2, 3, 4, 5}
dict_1 = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
dict_2 = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
sys.getsizeof(set_1) # 224
sys.getsizeof(set_2) # 736
sys.getsizeof(dict_1) # 240
sys.getsizeof(dict_2) # 368

See the result , Compare the screenshot of the previous section , It can be seen that : When the number of elements is equal , Statically created collections / The memory occupied by the dictionary is exactly the same as that of dynamic expansion .

Does this apply to list objects ? Look at it together. :

list_1 = ['a', 'b']
list_2 = ['a', 'b', 'c']
list_3 = ['a', 'b', 'c', 'd']
list_4 = ['a', 'b', 'c', 'd', 'e']
sys.getsizeof(list_1) # 80
sys.getsizeof(list_2) # 88
sys.getsizeof(list_3) # 96
sys.getsizeof(list_4) # 104

The screenshot from the previous section shows , The list is at the front 4 Every element takes up 96 byte , stay 5 The elements take up 128 byte , There is a clear contradiction .

therefore , The secret is clear : When the number of elements is equal , It is possible that the memory occupied by statically created list is smaller than that of dynamic expansion !

in other words , The two lists look the same , It's actually different ! A list is not equal to a list !

4、 Pruning elements does not free memory !
As mentioned earlier , When expanding a mutable object , May apply for new memory .

that , If you reduce the mutable objects in turn , After subtracting some elements , Will the newly applied memory be recycled automatically ?

import sys
a = [1, 2, 3, 4]
sys.getsizeof(a) # Initial value :96
a.append(5) # After expansion :[1, 2, 3, 4, 5]
sys.getsizeof(a) # After expansion :128
a.pop() # After reduction :[1, 2, 3, 4]
sys.getsizeof(a) # After reduction :128

As the code shows , The list expands and shrinks , Although back to the original , But the memory space occupied is not automatically released . Other mutable objects are the same .

This is it. Python The little secret of ,“ Fat people can't lose weight ”: It's easy for thin people to get fat , It's easy to cut back , But you can't lose weight , ha-ha ~~~

5、 An empty dictionary is not equal to an empty dictionary !
Use pop() Method , Only the elements in the mutable object are reduced , But it doesn't free up the memory space that has been requested .

There's another. clear() Method , It will empty all elements of the mutable object , Let's try :

import sys
a = [1, 2, 3]
b = {1, 2, 3}
c = {'a':1, 'b':2, 'c':3}
sys.getsizeof(a) # 88
sys.getsizeof(b) # 224
sys.getsizeof(c) # 240
a.clear() # After emptying :[]
b.clear() # After emptying :set()
c.clear() # After emptying :{}, That is to say dict()

call clear() Method , We get a few empty objects .

In the first section , Their memory size has been checked .( I said that I will take the exam , Please write it back )

however , If we check again at this time , You will be surprised to find out , The size of these empty objects is not exactly the same as the previous query !

# Take the previous empty operation :
sys.getsizeof(a) # 64
sys.getsizeof(b) # 224
sys.getsizeof(c) # 72

The size of empty lists and empty tuples remains the same , But an empty dictionary (72) It's better than the empty dictionary (240) It's a lot smaller !

in other words , Lists and tuples are empty after the elements , Go back to the starting point , However , The dictionary is “ throw the helve after the hatchet ”, Not only the “ eat ” All the people who went in vomited out , I also lost my old book !

The secret of the dictionary is very deep , To tell you the truth, I just learned , puzzled ……

That's all Python A few secrets when allocating memory , After watching the , Do you think you have gained insight ?

How many have you figured out

The above is all the content shared this time , Want to know more python Welcome to official account :Python Programming learning circle , send out “J” Free access to , Daily dry goods sharing


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved