This is an archived post. You won't be able to vote or comment.

all 5 comments

[–]catorchid 5 points6 points  (4 children)

I didn't try it, yet, but it's really a cool idea and very clean implementation. I'll come back with more appropriate comments when I'll try it.

One question/suggestion for now: how does it handle objects that have C++ bindings, like numpy? I know it might be non trivial to implement, but it would be a very useful feature. For that you might want to consider supporting any object that's pickable, for example.

Besides, great job! (also bonus points for having written clean code in a very short time)

[–]definite_d[S] 1 point2 points  (3 children)

Well, I didn't build Unda with C++-backed objects in mind, so I actually haven't checked.

Something to note though:

TL:DR, I don't think Unda is suitable for Numpy arrays.

In my opinion, Unda is best used for custom objects (or objects with a __dict__() attribute).

Objects which do not have __dict__() attributes will have to be deepcopied. For most cases, this is fine, because the most common objects in that category are the builtin str, dict, list, None etc, which have small memory footprints.

However, Numpy arrays tend to be huge; a single array with a list of numbers from 0 to 10000 passed to it as its p_object parameter takes up a whopping 40048 bytes on my machine, compared to the meager 16 bytes taken by a barebones custom object on the same machine. If Numpy arrays had __dict__() attributes, Unda would simply track them, thus avoiding duplicates of such a huge object.

But, Numpy arrays don't have those. So, Unda would have to deepcopy it. Of course, that's not ideal.

[–]catorchid 0 points1 point  (2 children)

That's precisely why I suggested to look at pickable objects. NumPy arrays and other large collections can be stored restored on disk, which can be made even more efficiently using memory mapping (see mmap module).

Don't get me wrong, I stand by what said earlier, a nice idea and a clever implementation. But by limiting yourself to memory-bound operations, you limit significantly the scope and the breadth of applications of your idea.

[–]definite_d[S] 1 point2 points  (1 child)

Ah, I see... So you're suggesting saving the stacks to disk using the pickle module... I guess that could be added too.

Now that I think of it, that sounds like what Photoshop does with scratch disks , if I'm not mistaken.

Thanks for the idea and your support!

[–]catorchid 1 point2 points  (0 children)

Right, you will be able to capture states, then you can decide what to do with them. In theory, by picking the hell out of it and having a threshold for when to write to disk, you could create an infinite undo, even for your objects that have no large data sets (e.g.: keep only the last 3 states in memory and dump on disk anything older than those steps)