Cjkjvfnby wrote: ↑Tue Sep 07, 2021 5:52 amAnd XML is used for server-client communication in multiplayer.
Non-binary-compatible client-server messages could be sent with compressed XML instead of raw text XML as well, if volume of data being sent is an issue. This should produce a smaller message size than changing the XML label sizes, at the cost of a bit of time unpacking the message.
Chars "items" took about 25 MB in the file. We could replace it with "i" and save 20 of them (0.5 MB in packed xml).
Specifically the
<item> XML tags are one of the more difficult cases to change. These appear in numerous
complicated bits of the Boost templated serialization code for standard containers, which I suspect would be error prone to change. I could just copy it all and change that string for a template specialization, but I'd be worried it would lead to compatibility issues with different versions of Boost.
The example there is a much simpler case: serialization of
std::pair. That would probably be possible, as there is no versioning of pair itself or tracking of the number of elements it contains like is needed for the container classes (that have "item" a bunch). The "first" and "second" can probably be changed to "f" and "s", and would probably substantially reduce the size of the XML text, since those two appear a lot, for all associative containers. I did this some time ago
for the similar Meter class.
Cjkjvfnby wrote: ↑Tue Sep 07, 2021 5:57 amI am not sure if we use/could have any benefits from multithreading for that task. In the theory process, some sections in parallel and write them in sequence could speed up saving a bit.
Code: Select all
ar & make_nvp(a) & make_nvp(b) -> x, y = parallel(make_nvp(a), make_nvp(b)); a & x & y
It's not that simple. The
make_nvp calls are just creating a temporary local pair of pointers, not doing any substantial (de)serialization work (ie. converting to text or creating objects in memory and assigning values after converting back from text). All that real work happens in
operator&, so that's what would need to be done in parallel. But
operator& modifies the archive it's called on, essentially to append serialized info to the archive or to consume serialized info to recreate the previously-serialized data. It thus can't be called in parallel on the same archive. Rather, one would need to have two separate archive objects and serialize stuff to and from them independently in parallel, probably starting at a high level, rather than the low level as suggested in your snippet. I started testing that last month:
https://github.com/freeorion/freeorion/ ... lSerialize
Cjkjvfnby wrote: ↑Tue Sep 07, 2021 6:11 amFox example universe object m_x double(64) could be changed to float(32).
I'd be hesitant, as lowering the precision of positions can lead to
weirdness for objects further from the centre of the universe coordinate space. Most other object state is tracked with float rather than double, but this specific case was a bit different due to the way positions are used. The choise of double instead of float for object positions was made considering main memory requirements, rather than size of serialized text representation, though.
Or even it could be multiplied by 1000 and changed to short (16).
Converting to and from a fixed-point representation just for serialization doesn't make sense, I think, as it would lead to actually different results between client and server or before and after saving and loading. Switching to a fixed point representation of object positions for the game mechanics internally might work, though I'm hesitant to do that as it's not trivial to implement and makes a lot of calculates more tricky to get right without a bunch of awkward conversions to and from floating point types. Maybe it'd be enough to store the positions internally as ints and have them be converted and scaled to and from floats whenever the rest of the game logic uses the values, but that's a lot of ifs for a questionable space savings vs. just compressing the text before sending over the network...
Edit: did a test implementation of storing positions internally as scaled int but using double values for all calculations of object positions:
https://github.com/freeorion/freeorion/commits/IntPos which makes UniverseObject XML look like
Code: Select all
<UniverseObject class_id="87" tracking_level="0" version="3">
<m_id>0</m_id>
<m_name>Alnath α</m_name>
<x>145544</x>
<y>240571</y>
<m_owner_empire_id>-1</m_owner_empire_id>
<m_system_id>-1</m_system_id>