Extremely slow message creation for large arrays in Python
@hidmic đang làm issue này rồi.
Từ ngày 22/4/2022.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
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:
- Operating System:
- Ubuntu 20.04
- Installation type:
- apt
- Version or commit hash:
- rolling
- Client library (if applicable):
- rclpy
Steps to reproduce issue
- Create a large Numpy Array called
nparr - Create a matching PointCloud2 message called
msgwith parameters matching the NumPy array format - Set the data
msg.data = nparr.tobytes() - Time this process and compare it to setting the data directly in the constructor
The second one is much slower:
- 2.7484822273254395 seconds # byte string set via the constructor
- 412.08923530578613 seconds # byte string set via the property
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
self.data = array.array('B', kwargs.get('data', []))
The setter itself checks if the cast is already done and skips the casing, including the following assertion
assert \
((isinstance(value, Sequence) or
isinstance(value, Set) or
isinstance(value, UserList)) and
not isinstance(value, str) and
not isinstance(value, UserString) and
all(isinstance(v, int) for v in value) and
all(val >= 0 and val < 256 for val in value)), \
"The 'data' field must be a set or sequence and each value of type 'int' and each unsigned integer in [0, 255]"
The following part of the assertion is critical because it massively slows it down by iterating >2x over all values.
all(isinstance(v, int) for v in value) and
all(val >= 0 and val < 256 for val in value))
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 https://github.com/ros2/common_interfaces/issues/177
- Ngôn ngữ chính
- EmberScript
- Star
- 26
- Fork
- 68
- Merge trung bình
- 1 ngày 9 giờ
- Pull request đã merge (30 ngày)
- 3
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của ros2/rosidl_python
-
Eliminate array resetting loop in _msg_support.c.emCó thể đã có người làm @Lidang-Jiang đã nhận 171 ngày trước. Đang mởenhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
ros2/rosidl_python#255 · 1 reaction ·
-
bug
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 56/100
ros2/rosidl_python#264 · 2 bình luận ·
-
Message named pkg/Duration with field builtin_interfaces/Duration is invalidCó thể đã có người làm @Lidang-Jiang đã nhận 171 ngày trước. Đang mởbug
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
ros2/rosidl_python#257 · 8 bình luận ·
-
enhancement
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
ros2/rosidl_python#242 ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 32/100
ros2/rosidl_python#219 · 2 bình luận ·