ManimCommunity / ManimCommunity/manim

Deprecate different signatures for updaters

Open
#321 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Python
Stars
40.9k
Forks
3.1k
Avg merge
3d 12h
Merged PRs (30d)
25

Description

The problem

This is part of mobject:mobject.update() method:

https://github.com/ManimCommunity/manim/blob/505470010995bc5f8b3c3bc33d6636699784f566/manim/mobject/mobject.py#L155-L163

L159 fetches the parameters of each updater, each time the object is updated, which may occur multiple times in a single animation, let alone a whole scene. Fetching the parameter list makes use of the inspect library, which is not the fastest thing in the world.

I think this is super unnecessary and adding a lot of overhead. This checking of the parameter list is done so that each updater can be called appropriately: either updater(self, dt), or just updater(self). The gain in convenience for the end user seems very small in comparison to the overhead that this incurs in.

A possible fix

My suggestion is that we should just make each updater always accept two arguments, and never check the parameter list. The chunk of code above could just become

    def update(self, dt=0, recursive=True):
        if self.updating_suspended:
            return self
        for updater in self.updaters:
            updater(self, dt)

No parameter fetching necessary.

Incidentally, the current version forces each updater function to name its second parameter dt, if it has one. With my proposal, updater functions' second argument may be called whatever the user wants. If an updater function doesn't need to use the second argument, they can just ignore it.

Example

Here's a scene.

from manim import Scene, Integer, VGroup, Transform

def dummy_updater(obj, dt):
    return [i**2 for i in range(100)]

class TestScene(Scene):
    def construct(self):
        number = Integer(0)
        for _ in range(1000):
            number.add_updater(dummy_updater)

        self.add(number)
        for i in range(10):
            self.play(Transform(number, Integer(i)))

When executed with the current master, I get

$ rm -r media/
$ time manim -l scene.py 
...suppressed manim output...
real	1m7.297s
user	0m57.463s
sys	0m2.940s

When ran with my suggestion:

$ rm -r media/
$ time manim -l scene.py 
...suppressed manim output...
real	0m43.912s
user	0m40.581s
sys	0m2.781s

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in manim/mobject/mobject.py at the linked update method, especially lines 155–163, and trace how updater functions are added and invoked. Review the example scene and existing updater usages to identify compatibility implications. Done means updater invocation no longer fetches parameter lists and the documented updater signature is consistently supported without breaking existing behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
performance
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.