Examining the code, I can see that adding an observer is quite efficient (Around logarithmic time). Adding the same observer to the same entity multiple times is safe, though not as efficient as it should be due to historical reasons. It will essentially detect that the given observer is already observing the target entity. If it does, it removes the internal observer first and creates a new one. To the Ruby side, it seems like nothing has happened, but the observer gets moved to the end of the queue. So @DanRathbun is right. But I’m not sure why this information would be useful to the API user. (There might be a reason I’m not thinking of). But it’s not wise from an API designer’s perspective to make such implementation details into API contracts. That severely limits our future ability to change these internal details and improve them later.
The current implementation of removing an observer is far less efficient. So I can believe that doing a batch remove on a huge model would take a long time. Looks like we have room for improvement there.
For better performance, it is a good idea to reduce the number of observers used. So it is better to observe entities at higher level, e.g. groups or instances rather than faces and edges, for instance.
And the reason there isn’t a way to get a list of all observers is that all plugins are currently running inside the same Ruby environment and we don’t have a mechanism to differentiate which plugin owns which observer. We wouldn’t want to hand you references to someone else’s observers, potentially letting you remove something you didn’t add.
I hope these help. Please consider these just as the current state of the code and not promises about how they will behave in the future.