More detailed information: ## With annotations === tracemalloc stat === traced: (46969277, 46983753) 18,048,888 / 181112 File "<frozen importlib._bootstrap_external>", line 488 File "<frozen importlib._bootstrap_external>", line 780 File "<frozen importlib._bootstrap_external>", line 675 === size by types === dict 9,083,816 (8,870.91KB) / 21846 = 415.811bytes (21.38%) tuple 6,420,960 (6,270.47KB) / 86781 = 73.990bytes (15.11%) str 6,050,213 (5,908.41KB) / 77527 = 78.040bytes (14.24%) function 2,772,224 (2,707.25KB) / 20384 = 136.000bytes (6.53%) code 2,744,888 (2,680.55KB) / 18987 = 144.567bytes (6.46%) type 2,713,552 (2,649.95KB) / 2769 = 979.975bytes (6.39%) bytes 2,650,838 (2,588.71KB) / 38723 = 68.456bytes (6.24%) set 2,445,280 (2,387.97KB) / 6969 = 350.880bytes (5.76%) weakref 1,255,600 (1,226.17KB) / 15695 = 80.000bytes (2.96%) list 707,336 (690.76KB) / 6628 = 106.719bytes (1.66%) === dict stat === t, size, total (%) / count 3, 256, 1,479,424 (15.68%) / 5779.0 3, 1,200, 1,330,800 (14.11%) / 1109.0 3, 1,310,832, 1,310,832 (13.90%) / 1.0 3, 664, 1,287,496 (13.65%) / 1939.0 7, 128, 756,352 (8.02%) / 5909.0 3, 384, 707,328 (7.50%) / 1842.0 3, 2,296, 642,880 (6.81%) / 280.0 0, 256, 378,112 (4.01%) / 1477.0 7, 168, 251,832 (2.67%) / 1499.0 3, 4,720, 221,840 (2.35%) / 47.0 3, 9,336, 130,704 (1.39%) / 14.0 7, 88, 105,072 (1.11%) / 1194.0 * t=7 key-sharing dict, t=3 interned string key only, t=1 string key only, t=0 non string key is used ## Stripped annotations === tracemalloc stat === traced: (42383739, 42397983) 18,069,806 / 181346 File "<frozen importlib._bootstrap_external>", line 488 File "<frozen importlib._bootstrap_external>", line 780 File "<frozen importlib._bootstrap_external>", line 675 === size by types === dict 7,913,144 (7,727.68KB) / 17598 = 449.662bytes (20.62%) tuple 6,149,120 (6,005.00KB) / 82734 = 74.324bytes (16.02%) str 6,070,083 (5,927.82KB) / 77741 = 78.081bytes (15.82%) code 2,744,312 (2,679.99KB) / 18983 = 144.567bytes (7.15%) type 2,713,552 (2,649.95KB) / 2769 = 979.975bytes (7.07%) bytes 2,650,464 (2,588.34KB) / 38715 = 68.461bytes (6.91%) function 2,547,280 (2,487.58KB) / 18730 = 136.000bytes (6.64%) set 1,423,520 (1,390.16KB) / 4627 = 307.655bytes (3.71%) list 634,472 (619.60KB) / 5454 = 116.331bytes (1.65%) int 608,784 (594.52KB) / 21021 = 28.961bytes (1.59%) === dict stat === t, size, total (%) / count 3, 1,200, 1,316,400 (16.06%) / 1097.0 3, 1,310,832, 1,310,832 (16.00%) / 1.0 3, 664, 942,216 (11.50%) / 1419.0 3, 256, 861,184 (10.51%) / 3364.0 3, 384, 657,024 (8.02%) / 1711.0 3, 2,296, 640,584 (7.82%) / 279.0 7, 128, 606,464 (7.40%) / 4738.0 0, 256, 379,904 (4.64%) / 1484.0 7, 168, 251,832 (3.07%) / 1499.0 3, 4,720, 221,840 (2.71%) / 47.0 3, 9,336, 130,704 (1.59%) / 14.0 7, 88, 105,248 (1.28%) / 1196.0 7, 256, 86,784 (1.06%) / 339.0 ## Stripped annotation + without pydebug === tracemalloc stat === traced: (37371660, 40814265) 9,812,083 / 111082 File "<frozen importlib._bootstrap>", line 205 File "<frozen importlib._bootstrap_external>", line 742 File "<frozen importlib._bootstrap_external>", line 782 6,761,207 / 85614 File "<frozen importlib._bootstrap_external>", line 488 File "<frozen importlib._bootstrap_external>", line 780 File "<frozen importlib._bootstrap_external>", line 675 ## Ideas about memory optimize a) Split PyGC_Head from object Reduces 2words (16byte) from each tuples. >>> 82734 * 16 / 1024 1292.71875 So estimated -1.2MB b) concat co_consts, co_names, co_varnames, co_freevars into one tuple, or embed them into code. Each tuple has 3 (gc head) + 3 (refcnt, *type, length) = 6 words overhead. (or 4 words if (a) is applied) If we can reduce 3 tuples, 18 words = 144byte (or 12 words=96byte) can be reuduced. >>> 18983 * 144 2733552 >>> 18983 * 96 1822368 But co_freevars is empty tuple in most cases. So real effect is smaller than 2.7MB. If we can embed them into code object, we can estimate -2.7MB. (There are co_cellvars too. But I don't know about it much, especially it is GC tracked or not) c) (interned) string key only dict. 20% of memory is used for dict, and 70% of dict has interned string keys. Current DictKeyEntry is 3 words: {key, hash, value}. But if we can assume all key is string, hash can be get from the key. If we use 2 words entry: {key, value} for such dict, I think dict can be 25% smaller. >>> 7913144 * 0.25 / 1024 1931.919921875 So I estimate -1.9MB If we can implement (a)~(c) I estimate memory usage on Python (--without-pydebug) can be reduced from 35.6MB to 30MB, roughly. But I think -Onoannotation option is top priority. It can reduce 4MB, even we use annotations only in our code. If major libraries start using annotations, this number will be larger.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4