Reducing Python String Memory Use in Apache Arrow 0.12 (2019)
arrow.apache.org
arrow.apache.org
dedup = {}
for s in strings:
s = dedup.setdefault(s, s)
# Do something with s
It hashes each string "s" and looks in the dictionary "dedup" to see if there's an existing string object previously in the list "strings", in which case it uses it, and otherwise it stores the current string object in "dedup". for s in strings:
s = sys.intern(s)
# Do something with s
Depending on your application lifecycle you may want to shove the dedup'd strings in a set (or in a list, after checking if the identity of what you got from `sys.intern` is different than what you put in) in order to keep them alive: `sys.intern` does not do that."Interned strings are not immortal; you must keep a reference to the return value of intern() around to benefit from it"
Also the second paragraph of my comment.
s = dedup.setdefault(s, s)
There's not an obvious way to get the object in a set that matches a value you have. @functools.cache
def dedup(s):
return sys.intern(s)It happened a long time ago, but I think I misread something about sys.intern not being able to handle lots and lots of strings, so I added an extra layer of caching, but it looks like it's not needed anymore.
[1]: https://github.com/python/cpython/blob/3.10/Objects/unicodeo...