Skip to content

Overhead of SingletonGate.__new__  #10867

@mtreinish

Description

@mtreinish

In #10314 we introduced a new SingletonGate class which is used as the parent for many standard library gates. This class enables us to use a single shared instance for these gates which greatly reduces our memory overhead for repeated gates in a circuit. However, the manner in which implemented this object reuse is by overloading __new__ in the SingletonGate class which determines if the instance should be a singleton or a mutable copy and returns that. However, using __new__ has noticeable impact on runtime for creating new objects. @jakelishman outlined some of the reasons for this overhead in his comment on #10865:

Fwiw, there's a bunch of "hidden" overhead of SingletonGate.__new__ in that:

  • making the __new__ an extra Python-space call over object.__new__ adds cost of itself
  • even if we return the singleton instance from __new__, the resulting __init__ still gets called if the type of return value is in the inheritance chain of the original object.

One potential way around this is to have the singleton class be a metaclass that overrides type.__call__ with a new method that returns the singleton instance without calling the __new__ machinery at all. That will avoid __init__ from being called at all, so > we'll gain really a bunch of the time there. The downside is that there's a metaclass conflict: Operation's metaclass is ABCMeta, so we can't (naively) make SingletonGate > a metaclass. However, we could make SingletonGateMeta derive from ABCMeta, which would resolve the conflict, even if we'd need to take care to maintain that relationship were Operation ever to change.

Originally posted by @jakelishman in #10865 (comment)

This overhead for object creation goes from previously being ~666ns for a class directly inheriting from Gate to ~5us changing the parent to SingletonGate. We should investigate different techniques to mitigate the runtime impact here.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions