Skip to content

Commit d4f3954

Browse files
ASCWriter speed improvement (#1856)
* ASCWriter speed improvement Changed how the message data is converted to string. This results in and 100% speed improvement. On my PC, before the change, logging 10000 messages was taking ~16 seconds and this change drop it to ~8 seconds. With this change, the ASCWriter is still one of the slowest writer we have in Python-can. * Update asc.py * Update logformats_test.py * Create single_frame.asc * Update logformats_test.py * Update test/logformats_test.py Co-authored-by: Felix Divo <4403130+felixdivo@users.noreply.github.com> --------- Co-authored-by: Felix Divo <4403130+felixdivo@users.noreply.github.com>
1 parent 757370d commit d4f3954

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

can/io/asc.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import logging
1010
import re
1111
from datetime import datetime
12-
from typing import Any, Dict, Final, Generator, List, Optional, TextIO, Union
12+
from typing import Any, Dict, Final, Generator, Optional, TextIO, Union
1313

1414
from ..message import Message
1515
from ..typechecking import StringPathLike
@@ -439,10 +439,10 @@ def on_message_received(self, msg: Message) -> None:
439439
return
440440
if msg.is_remote_frame:
441441
dtype = f"r {msg.dlc:x}" # New after v8.5
442-
data: List[str] = []
442+
data: str = ""
443443
else:
444444
dtype = f"d {msg.dlc:x}"
445-
data = [f"{byte:02X}" for byte in msg.data]
445+
data = msg.data.hex(" ").upper()
446446
arb_id = f"{msg.arbitration_id:X}"
447447
if msg.is_extended_id:
448448
arb_id += "x"
@@ -462,7 +462,7 @@ def on_message_received(self, msg: Message) -> None:
462462
esi=1 if msg.error_state_indicator else 0,
463463
dlc=len2dlc(msg.dlc),
464464
data_length=len(msg.data),
465-
data=" ".join(data),
465+
data=data,
466466
message_duration=0,
467467
message_length=0,
468468
flags=flags,
@@ -478,6 +478,6 @@ def on_message_received(self, msg: Message) -> None:
478478
id=arb_id,
479479
dir="Rx" if msg.is_rx else "Tx",
480480
dtype=dtype,
481-
data=" ".join(data),
481+
data=data,
482482
)
483483
self.log_event(serialized, msg.timestamp)

test/data/single_frame.asc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
date Sat Sep 30 15:06:13.191 2017
2+
base hex timestamps absolute
3+
internal events logged
4+
Begin Triggerblock Sat Sep 30 15:06:13.191 2017
5+
0.000000 Start of measurement
6+
0.000000 1 123x Rx d 40 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
7+
End TriggerBlock

test/logformats_test.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,33 @@ def test_write_millisecond_handling(self):
651651

652652
self.assertEqual(expected_file.read_text(), actual_file.read_text())
653653

654+
def test_write(self):
655+
now = datetime(
656+
year=2017, month=9, day=30, hour=15, minute=6, second=13, microsecond=191456
657+
)
658+
659+
# We temporarily set the locale to C to ensure test reproducibility
660+
with override_locale(category=locale.LC_TIME, locale_str="C"):
661+
# We mock datetime.now during ASCWriter __init__ for reproducibility
662+
# Unfortunately, now() is a readonly attribute, so we mock datetime
663+
with patch("can.io.asc.datetime") as mock_datetime:
664+
mock_datetime.now.return_value = now
665+
writer = can.ASCWriter(self.test_file_name)
666+
667+
msg = can.Message(
668+
timestamp=now.timestamp(),
669+
arbitration_id=0x123,
670+
data=range(64),
671+
)
672+
673+
with writer:
674+
writer.on_message_received(msg)
675+
676+
actual_file = Path(self.test_file_name)
677+
expected_file = self._get_logfile_location("single_frame.asc")
678+
679+
self.assertEqual(expected_file.read_text(), actual_file.read_text())
680+
654681

655682
class TestBlfFileFormat(ReaderWriterTest):
656683
"""Tests can.BLFWriter and can.BLFReader.

0 commit comments

Comments
 (0)