From 1741680a5da86a24472e28b7095d67a74e96fc4b Mon Sep 17 00:00:00 2001 From: Zoltan Beck Date: Wed, 16 Oct 2024 11:37:34 +0900 Subject: [PATCH 1/4] Speedup conversion of arrays and numpy arrays The `_convert_value` function takes a lot of time converting array types, especially making conversion of image types very slow. This change accelerates this conversion when the complete images are handled (`no_arr` option is off, no truncation applied). Signed-off-by: Zoltan Beck --- rosidl_runtime_py/convert.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rosidl_runtime_py/convert.py b/rosidl_runtime_py/convert.py index ac8c5c1..ae456be 100644 --- a/rosidl_runtime_py/convert.py +++ b/rosidl_runtime_py/convert.py @@ -211,6 +211,8 @@ def _convert_value( value = '>'.format(len(value)) elif truncate_length is not None and len(value) > truncate_length: value = value[:truncate_length] + '...' + elif isinstance(value, (array.array, numpy.ndarray)) and not no_arr and truncate_length is None: + value = value.tolist() elif isinstance(value, (list, tuple, array.array, numpy.ndarray)): # Since arrays and ndarrays can't contain mixed types convert to list typename = tuple if isinstance(value, tuple) else list From 0bc06b4cd18c0a21502db0323e266b309da3963e Mon Sep 17 00:00:00 2001 From: Zoltan Beck Date: Wed, 16 Oct 2024 21:55:35 +0900 Subject: [PATCH 2/4] lint fix Signed-off-by: Zoltan Beck --- rosidl_runtime_py/convert.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/rosidl_runtime_py/convert.py b/rosidl_runtime_py/convert.py index ae456be..762bb52 100644 --- a/rosidl_runtime_py/convert.py +++ b/rosidl_runtime_py/convert.py @@ -187,7 +187,7 @@ def message_to_ordereddict( value = getattr(msg, field_name, None) value = _convert_value( value, field_type=field_type, - truncate_length=truncate_length, no_arr=no_arr, no_str=no_str) + truncate_len=truncate_length, no_arr=no_arr, no_str=no_str) d[field_name] = value return d @@ -196,39 +196,39 @@ def _convert_value( value, *, field_type=None, - truncate_length=None, + truncate_len=None, no_arr=False, no_str=False ): if isinstance(value, bytes): - if truncate_length is not None and len(value) > truncate_length: - value = ''.join([chr(c) for c in value[:truncate_length]]) + '...' + if truncate_len is not None and len(value) > truncate_len: + value = ''.join([chr(c) for c in value[:truncate_len]]) + '...' else: value = ''.join([chr(c) for c in value]) elif isinstance(value, str): if no_str is True: value = '>'.format(len(value)) - elif truncate_length is not None and len(value) > truncate_length: - value = value[:truncate_length] + '...' - elif isinstance(value, (array.array, numpy.ndarray)) and not no_arr and truncate_length is None: + elif truncate_len is not None and len(value) > truncate_len: + value = value[:truncate_len] + '...' + elif isinstance(value, (array.array, numpy.ndarray)) and not no_arr and truncate_len is None: value = value.tolist() elif isinstance(value, (list, tuple, array.array, numpy.ndarray)): # Since arrays and ndarrays can't contain mixed types convert to list typename = tuple if isinstance(value, tuple) else list if no_arr is True and field_type is not None: value = __abbreviate_array_info(value, field_type) - elif truncate_length is not None and len(value) > truncate_length: + elif truncate_len is not None and len(value) > truncate_len: # Truncate the sequence - value = value[:truncate_length] + value = value[:truncate_len] # Truncate every item in the sequence value = typename( - [_convert_value(v, truncate_length=truncate_length, + [_convert_value(v, truncate_len=truncate_len, no_arr=no_arr, no_str=no_str) for v in value] + ['...']) else: # Truncate every item in the list value = typename( - [_convert_value(v, truncate_length=truncate_length, + [_convert_value(v, truncate_len=truncate_len, no_arr=no_arr, no_str=no_str) for v in value]) elif isinstance(value, dict) or isinstance(value, OrderedDict): # Convert each key and value in the mapping @@ -236,14 +236,14 @@ def _convert_value( for k, v in value.items(): # Don't truncate keys because that could result in key collisions and data loss new_value[_convert_value(k)] = _convert_value( - v, truncate_length=truncate_length, no_arr=no_arr, no_str=no_str) + v, truncate_len=truncate_len, no_arr=no_arr, no_str=no_str) value = new_value elif isinstance(value, numpy.number): value = value.item() elif not isinstance(value, (bool, float, int)): # Assuming value is a message since it is neither a collection nor a primitive type value = message_to_ordereddict( - value, truncate_length=truncate_length, no_arr=no_arr, no_str=no_str) + value, truncate_length=truncate_len, no_arr=no_arr, no_str=no_str) return value From 4af1e69ab31d017f3b3929252a2acd6729afd996 Mon Sep 17 00:00:00 2001 From: Zoltan Beck Date: Fri, 6 Dec 2024 14:02:00 +0900 Subject: [PATCH 3/4] Revert "lint fix" This reverts commit 6e9c9915ad2d501ad9a6b97088fee9b88915994f. Signed-off-by: Zoltan Beck --- rosidl_runtime_py/convert.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/rosidl_runtime_py/convert.py b/rosidl_runtime_py/convert.py index 762bb52..ae456be 100644 --- a/rosidl_runtime_py/convert.py +++ b/rosidl_runtime_py/convert.py @@ -187,7 +187,7 @@ def message_to_ordereddict( value = getattr(msg, field_name, None) value = _convert_value( value, field_type=field_type, - truncate_len=truncate_length, no_arr=no_arr, no_str=no_str) + truncate_length=truncate_length, no_arr=no_arr, no_str=no_str) d[field_name] = value return d @@ -196,39 +196,39 @@ def _convert_value( value, *, field_type=None, - truncate_len=None, + truncate_length=None, no_arr=False, no_str=False ): if isinstance(value, bytes): - if truncate_len is not None and len(value) > truncate_len: - value = ''.join([chr(c) for c in value[:truncate_len]]) + '...' + if truncate_length is not None and len(value) > truncate_length: + value = ''.join([chr(c) for c in value[:truncate_length]]) + '...' else: value = ''.join([chr(c) for c in value]) elif isinstance(value, str): if no_str is True: value = '>'.format(len(value)) - elif truncate_len is not None and len(value) > truncate_len: - value = value[:truncate_len] + '...' - elif isinstance(value, (array.array, numpy.ndarray)) and not no_arr and truncate_len is None: + elif truncate_length is not None and len(value) > truncate_length: + value = value[:truncate_length] + '...' + elif isinstance(value, (array.array, numpy.ndarray)) and not no_arr and truncate_length is None: value = value.tolist() elif isinstance(value, (list, tuple, array.array, numpy.ndarray)): # Since arrays and ndarrays can't contain mixed types convert to list typename = tuple if isinstance(value, tuple) else list if no_arr is True and field_type is not None: value = __abbreviate_array_info(value, field_type) - elif truncate_len is not None and len(value) > truncate_len: + elif truncate_length is not None and len(value) > truncate_length: # Truncate the sequence - value = value[:truncate_len] + value = value[:truncate_length] # Truncate every item in the sequence value = typename( - [_convert_value(v, truncate_len=truncate_len, + [_convert_value(v, truncate_length=truncate_length, no_arr=no_arr, no_str=no_str) for v in value] + ['...']) else: # Truncate every item in the list value = typename( - [_convert_value(v, truncate_len=truncate_len, + [_convert_value(v, truncate_length=truncate_length, no_arr=no_arr, no_str=no_str) for v in value]) elif isinstance(value, dict) or isinstance(value, OrderedDict): # Convert each key and value in the mapping @@ -236,14 +236,14 @@ def _convert_value( for k, v in value.items(): # Don't truncate keys because that could result in key collisions and data loss new_value[_convert_value(k)] = _convert_value( - v, truncate_len=truncate_len, no_arr=no_arr, no_str=no_str) + v, truncate_length=truncate_length, no_arr=no_arr, no_str=no_str) value = new_value elif isinstance(value, numpy.number): value = value.item() elif not isinstance(value, (bool, float, int)): # Assuming value is a message since it is neither a collection nor a primitive type value = message_to_ordereddict( - value, truncate_length=truncate_len, no_arr=no_arr, no_str=no_str) + value, truncate_length=truncate_length, no_arr=no_arr, no_str=no_str) return value From 2dbc7b1423a216d0e34563441fa5005b88663a26 Mon Sep 17 00:00:00 2001 From: Zoltan Beck Date: Fri, 6 Dec 2024 14:08:30 +0900 Subject: [PATCH 4/4] fix lint with longer argument name Signed-off-by: Zoltan Beck --- rosidl_runtime_py/convert.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rosidl_runtime_py/convert.py b/rosidl_runtime_py/convert.py index ae456be..1a45e89 100644 --- a/rosidl_runtime_py/convert.py +++ b/rosidl_runtime_py/convert.py @@ -211,7 +211,11 @@ def _convert_value( value = '>'.format(len(value)) elif truncate_length is not None and len(value) > truncate_length: value = value[:truncate_length] + '...' - elif isinstance(value, (array.array, numpy.ndarray)) and not no_arr and truncate_length is None: + elif ( + isinstance(value, (array.array, numpy.ndarray)) + and not no_arr + and truncate_length is None + ): value = value.tolist() elif isinstance(value, (list, tuple, array.array, numpy.ndarray)): # Since arrays and ndarrays can't contain mixed types convert to list