-
Notifications
You must be signed in to change notification settings - Fork 45
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
Extremely slow message creation for large arrays in Python #156
Comments
Just a question; why is this > 2x? Isn't it just 2x + a constant amount for all of the
So I would say that the general problem here is that we don't know the type of the values that are being passed in. We don't even know that they are all the same type, which is why we have the check for if they are an So with that said, I think the right thing to do here would probably be to special-case a bytestring so that we just assign it directly without doing the check on it. To do that, you would generally modify the code at rosidl_python/rosidl_generator_py/resource/_msg.py.em Lines 463 to 521 in 3dc5872
|
I am a bit confused as well. Maybe I thought this was a list comprehension and not a generator comprehension, causing another iteration by the
Correct me if I am wrong, but this is only the case if an iterable python object containing references to all elements is passed. A check is definitely required in this case. But the described issue focused on data provided as a bytestring. Checking each byte passes both restrictions/checks by design. This should lead to them being skipped as you suggested. I will try to wrap my head around the templating and suggest a solution. |
I agree that we'd have to specialize, but I'd suggest we specialize for |
The message serialization is very slow (> hundred seconds for large point clouds), when setting the data property of a PointCloud2 message in Python by passing a byte string (e.g. by NumPy
asbytes()
).This does not happen if the PointCloud2 message constructor is used (see #155 for the inconsistent behavior) or if a
array.array is passed
(does not work with the constructor because of #176).Bug report
Required Info:
Steps to reproduce issue
nparr
msg
with parameters matching the NumPy array formatmsg.data = nparr.tobytes()
The second one is much slower:
Expected behavior
Both should be equally fast
Actual behavior
The second one is much slower, because an additional assertion is performed.
This assertion is skipped in the constructor because of the bug in #155. It therefore performs much better.
The constructor directly casts the data and sends it to the setter
The setter itself checks if the cast is already done and skips the casing, including the following assertion
The following part of the assertion is critical because it massively slows it down by iterating >2x over all values.
This happens only in
__debug__
is set, but that is the case for many dev machines, and this effectively crashes the code by freezing for many seconds.Implementation considerations
Drop the check for byte strings. As it does not make any sense in the case of this datatype ether way.
I honestly don't know how to change this since the templating seems quite complex. Some advice would be appreciated.
Issue moved from ros2/common_interfaces#177
The text was updated successfully, but these errors were encountered: