-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance regression caused by #7087 #7528
Comments
After a bit of experimenting with the first problematic testcase (
What would be the best way to proceed? Should we get rid of dependence on ABC? Should we try to optimize the number of times |
The We can't give up Perhaps we could define a lightweight metaclass that inherits from |
For topological ordering, can we eventually get rid of using |
For topological sort we shouldn't be relying on isinstance anywhere. For the lexicographical topological sort we do the tie breaking string sort key is |
The sort key here is specific to edit: Matthew just said something pretty similar haha. I don't see why we should have a |
So it seems we should live |
I think you've misunderstood me here - I think the best way to treat the performance is to change the base class of I'd agree that using run-time type information is bad if you're trying switch on all possible subclass instances to do something different - that's absolutely something polymorphism should be used for - but in this case there is specialist behaviour that is necessary only for one specific subinterface to
|
I think this needs some more investigation before picking a direction here, especially to determine if we would expect this slow-down to grow as we increase either the number of operations in a circuit, the number of operation-types or something else.
>>> ABCMeta._dump_registry(Gate)
Class: qiskit.circuit.gate.Gate
Inv. counter: 60
_abc_registry: set()
_abc_cache: {<weakref at 0x13f23fdd0; to 'ABCMeta' at 0x7feff5cf5be0 (XGate)>}
_abc_negative_cache: set()
_abc_negative_cache_version: 60
https://qiskit.github.io/qiskit/#circuit_construction.CircuitConstructionBench.time_circuit_construction?commits=05b60a5e
Possibly helpful reference: https://stackoverflow.com/questions/42378726/why-is-checking-isinstancesomething-mapping-so-slow |
After investigating this a bit more (using
is faster than calling (polymorphic) functions:
and in the PR we have indeed changed Here are some numbers on a toy example, with classes
So, working with fields directly (especially I have tried to implement @jakelishman 's suggestion as follows (and probably did not do it fully correctly):
but on the toy example it did not improve things compared to inheriting from
|
Thanks for looking into this @alexanderivrii .
Interesting, this seems like a likely culprit. It might be interesting to see if this can be mitigated by using class-level attributes, e.g. class Clifford(Operation):
name = 'clifford'
def __init__(...):
.... This should satisfy the
I believe you should be able to attach files in the Github UI (by clicking the lower bar or drag and drop), but failing that, flamegraphs or cProfile outputs are still helpful. |
For 0.20, since the circuit and transpiler are still using |
Environment
What is happening?
The nightly benchmark runs have flagged several run time performance regressions after #7087 merged:
none are huge in absolute time (on the order of
ms
) and likely won't be noticeable in a largertranspile()
call or application but we should try to fix these because #7087 really shouldn't have had any performance impact.How can we reproduce the issue?
Run any of the transpiler passes identified in the regressions linked
What should happen?
The addition of a new abstract class defining the interface for a circuit operation shouldn't cause a noticeable performance regression
Any suggestions?
Identify where the passes are spending more time after the addition of the
Operation
class and fix the bottleneck.The text was updated successfully, but these errors were encountered: