Perform a fast deep copy of the provided value. This function is designed primary to operate on values of a simple type (think JSON types - dicts, lists, arrays, strings, ints). It's up to 10x faster compared to copy.deepcopy(). In case the provided value contains non-simple
(value, fall_back_to_deepcopy=True)
| 30 | |
| 31 | |
| 32 | def fast_deepcopy_dict(value, fall_back_to_deepcopy=True): |
| 33 | """ |
| 34 | Perform a fast deep copy of the provided value. |
| 35 | |
| 36 | This function is designed primary to operate on values of a simple type (think JSON types - |
| 37 | dicts, lists, arrays, strings, ints). |
| 38 | |
| 39 | It's up to 10x faster compared to copy.deepcopy(). |
| 40 | |
| 41 | In case the provided value contains non-simple types, we simply fall back to "copy.deepcopy()". |
| 42 | This means that we can still use it on values which sometimes, but not always contain complex |
| 43 | types - in that case, when value doesn't contain complex types we will perform much faster copy |
| 44 | and when it does, we will simply fall back to copy.deepcopy(). |
| 45 | |
| 46 | :param fall_back_to_deepcopy: True to fall back to copy.deepcopy() in case we fail to fast deep |
| 47 | copy the value because it contains complex types or similar |
| 48 | :type fall_back_to_deepcopy: ``bool`` |
| 49 | """ |
| 50 | # NOTE: ujson / orjson round-trip is up to 10 times faster on smaller and larger dicts compared |
| 51 | # to copy.deepcopy(), but it has some edge cases with non-simple types such as datetimes, class |
| 52 | # instances, etc. |
| 53 | try: |
| 54 | value = orjson.loads(orjson.dumps(value, default=default)) |
| 55 | except (OverflowError, ValueError, TypeError) as e: |
| 56 | if not fall_back_to_deepcopy: |
| 57 | raise e |
| 58 | |
| 59 | value = copy.deepcopy(value) |
| 60 | |
| 61 | return value |
no outgoing calls