In addition to what others have mentioned, at this scale, you might get
significant gains by adjusting your s-expression language.
For example, instead of this:
(pmem_flush
(threadId 140339047277632)
(startTime 923983542377819)
(elapsedTime 160)
(result 0)
(addr 0x7fa239055954)
(length 1))
(pmem_drain
(threadId 140339047277632)
(startTime 923983542378153)
(elapsedTime 83)
(result 0))
You could reduce consing by making each name-value pair be a single
Racket pair, rather than a proper list:
(pmem_flush
(threadId . 140339047277632)
(startTime . 923983542377819)
(elapsedTime . 160)
(result . 0)
(addr . 0x7fa239055954)
(length . 1))
(pmem_drain
(threadId . 140339047277632)
(startTime . 923983542378153)
(elapsedTime . 83)
(result . 0))
The proper list is what you'd want for a human language, and in most
applications the extra cost would be negligible, but you might have an
application in which it matters.
Your file size grows by an extra 2 bytes per pair, though, and this will
also have a small additional I/O handling cost.
Another thing you could do is, if one of your message types (like
`pmem_flush`) always/often has the same attribute names, is to make the
attributes "positional":
#(pmem_flush 140339047277632 923983542377819 160 0 0x7fa239055954 1)
#(pmem_drain 140339047277632 923983542378153 83 0)
If what's currently `pmem_flush` usually has the same attribute names,
but occasionally has an extra one, and you don't want to always be
filling in `#f`, maybe you want a `pmem_flush` with the positional
attributes, and `pmem_flush_extra` that has an extra positional attribute.
If the possible variations of `pmem_flush` are more complicated, maybe
`pmem_flush` with positional, in the usual case; and `pmem_flush_named`
with named attributes or a hybrid of positional and named, in the
complicated cases. Then you have the various development costs of two
ways of doing one thing, but sometimes that happens in runtime
performance optimization.
I used a Racket vector here, to suggest fast direct access to the
attribute values, but if you used a list, you could destructure it to
named variables/slots with `apply` and `lambda` (or with `apply` and a
`struct` constructor, if that made sense).
If you still find that this data interchange I/O is expensive, you can
always second-guess whether the reader is a win (over, say, a Unix-y
spaces-and-linefeeds format, or a binary format). But usually the
reader is fast.
BTW, some Algorithms 101 text once told me that constants don't matter,
only complexity, but that noble lie was just confusing. :)
--
You received this message because you are subscribed to the Google Groups "Racket
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.