Alternative to deepcopy a lit of BitVectors in python
<p>In my project, I am using <code>deepcopy()</code> function to create a deep copy a list of <code>BitVector</code>s. Unfortunately, its taking a lot of time. </p>

<pre><code>a = [&lt;BitVector obj at 0x000...&gt;, &lt;BitVector obj at 0x000...&gt;, &lt;BitVector obj at 0x000...&gt; ...]
</code></pre>

<p>On changing <code>a</code>, I do not want <code>b</code> to reflect the changes. </p>

<pre><code>b = deepcopy(a)
</code></pre>

<p>But the above equation is taking a lot of time. What alternative should I use for better performance?</p>

<p>The <code>BitVector</code> implementation is pure python and copying could be optimised substantially. Further, the provided implementation of <code>BitVector.deep_copy</code> is substantially slower than <code>copy.deepcopy</code>. Here is a an implementation of a deep copy that is ~10 times faster on my machine.</p>

<pre><code>def bitvector_copy(bitvector):
    new = BitVector.__new__(BitVector)
    new.__dict__ = {
        "size": bitvector.size, # size is an int and immutable
        "vector": bitvector.vector[:], # vector is an array, this is enough to get a deepcopy
        # the copy will be disassociated with any file it originated from
        # this emulates how BitVector.deep_copy works
        "filename": None,
        "FILEIN": None,
        "FILEOUT": None
    }
    return new
</code></pre>

<p>To copy your list you would now do:</p>

<pre><code>new_list = [bitvector_copy(vec) for vec in old_list]
</code></pre>

<p>For most use cases that should be enough. However, this isn't an exact deep copy though. Whilst all the new <code>BitVector</code>s are independent, it causes problems if the list contains references to the same bit vector eg.</p>

<pre><code>old_list = [BitVector(size=8)] * 2
assert old_list[0] is old_list[1]
new_list = [bitvector_copy(vec) for vec in old_list]
assert new_list[0] is new_list[1] # AssertionError!
</code></pre>

<p>With a few modifications you can modify the copy function to work with <code>copy.deepcopy</code> and have the function return a true deep copy. This does slow the copying down a little bit though.</p>

<pre><code>def bitvector_deepcopy(self, memo):
    if id(self.vector) in memo:
        vector = memo[id(self.vector)]
    else:
        vector = memo[id(self.vector)] = self.vector[:]
    new = BitVector.__new__(BitVector)
    new.__dict__ = {
        "size": self.size,
        "vector": vector,
        "filename": None,
        "FILEIN": None,
        "FILEOUT": None
    }
    return new
BitVector.__deepcopy__ = bitvector_deepcopy
</code></pre>

python python-3.x deep-copy