-
Notifications
You must be signed in to change notification settings - Fork 748
Improve performance of unwrapping .NET objects passed from Python #930
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
Conversation
This addresses the following scenario: 1. A C# object `a` is created and filled with some data. 2. `a` is passed via Python.NET to Python. To do that Python.NET creates a wrapper object `w`, and stores reference to `a` in one of its fields. 3. Python code later passes `w` back to C#, e.g. calls `SomeCSharpMethod(w)`. 4. Python.NET has to unwrap `w`, so it reads the reference to `a` from it. Prior to this change in 4. Python.NET had to determine what kind of an object `a` is. If it is an exception, a different offset needed to be used. That check was very expensive (up to 4 calls into Python interpreter). This change replaces that check with computing offset unconditionally by subtracting a constant from the object size (which is read from the wrapper), thus avoiding calls to Python interpreter.
2dea84a
to
39add65
Compare
Codecov Report
@@ Coverage Diff @@
## master #930 +/- ##
==========================================
- Coverage 86.66% 86.33% -0.34%
==========================================
Files 1 1
Lines 300 300
==========================================
- Hits 260 259 -1
- Misses 40 41 +1
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs c2ddaa0 to be cherry-picked into this branch.
Sorry for the delay, cherry-picking didn't work (I assume the given commit is not in any of the branches on the main fork). |
Hm, it shows in this fork. This is a very small change though, you can copy it manually. |
I did (just before commenting ;)). |
…ed in Lost Tech branch )
…thonnet#930) This addresses the following scenario: 1. A C# object `a` is created and filled with some data. 2. `a` is passed via Python.NET to Python. To do that Python.NET creates a wrapper object `w`, and stores reference to `a` in one of its fields. 3. Python code later passes `w` back to C#, e.g. calls `SomeCSharpMethod(w)`. 4. Python.NET has to unwrap `w`, so it reads the reference to `a` from it. Prior to this change in 4. Python.NET had to determine what kind of an object `a` is. If it is an exception, a different offset needed to be used. That check was very expensive (up to 4 calls into Python interpreter). This change replaces that check with computing offset unconditionally by subtracting a constant from the object size (which is read from the wrapper), thus avoiding calls to Python interpreter. Co-authored-by: Victor Milovanov <lost@losttech.software>
Upstreams QuantConnect#31 by @lostmsu.
Comment by the author:
This addresses the following scenario:
a
is created and filled with some data.a
is passed via Python.NET to Python. To do that Python.NET creates a wrapper objectw
, and stores reference toa
in one of its fields.w
back to C#, e.g. callsSomeCSharpMethod(w)
.w
, so it reads the reference toa
from it.Prior to this change in 4. Python.NET had to determine what kind of an object
a
is. If it is an exception, a different offset needed to be used. That check was very expensive (up to 4 calls into Python interpreter).This change replaces that check with computing offset unconditionally by subtracting a constant from the object size (which is read from the wrapper), thus avoiding calls to Python interpreter.