trilemma-dev / SecureXPC

A simple and secure XPC framework for Swift
MIT License
77 stars 15 forks source link

Improve `Data` encoding efficiency by using its native XPC representation #7

Closed amomchilov closed 2 years ago

amomchilov commented 2 years ago

I think we should support the native xpc_data type


(That said, does it actually end up as a string?).

It's much worse than that. Storing it as a string (with say, Base64 for example), would have a 1.6x overhead (5 bits of payload per 8 bit character). The current encoding has an 8x overhead. It encodes one UInt8 of payload per UInt64 of payload.

Here's a section of one of my long comments

I think this is easy enough to do that it might be worth doing.

In particular, I've noticed that Data is really inefficient to encode. As it is today, it bloats sizes by 8x. It tries to encode itself as a [UInt8], but each byte gets widened into an 8 byte int64 in order to be passed to xpc_int64_create. Luckily, there is not per-number object allocation overhead there (that would have been brutal for my use-case haha), because the only possible int64 values here would be 0-255, all of which fit into the tagged pointer representation.

You can get a rough of idea of what that might look like, here: https://github.com/amomchilov/SecureXPC/compare/add-intial-tests-for-XPCEncoder...Alex/new-scalar-support . Of course, I only changed the encoder half, and the decoder would need to match.

_Originally posted by @amomchilov in https://github.com/trilemma-dev/SecureXPC/pull/6#discussion_r743985682_

jakaplan commented 2 years ago

Splitting apart the problem and the solution spaces here, what specifically are the problems?

I'd likely prefer to solve the problems involved with encoding/decoding a type like Data as opposed to solving the issue exclusively for Data.

jakaplan commented 2 years ago

@amomchilov I've committed a generalized solution for any type of encoding/decoding involving unkeyed containers of exclusively fixed size elements. While this implementation does nothing special for Data, it's encoding into an XPC type should now have no size overhead. Unsurprisingly it does have some additional CPU and memory overhead in order to achieve this. Let me know if you consider this sufficient for your needs.

Regardless, this optimization should help when passing large arrays of smaller sized types.

amomchilov commented 2 years ago

I haven’t gotten far enough in my implementation to have anything to profile, but I’m guessing this will be a perf bottle neck for me.

Ill update you once I have data (pun intended) on the matter

jakaplan commented 2 years ago

@amomchilov Did you get to a point where you determine the performance of your approach and whether SecureXPC was a hinderance?

amomchilov commented 2 years ago

I've punted the featured that was going to be most sensitive to this, which is basically transmitting time series data that would be used to populate a chart. Each data point has a timestamp associated, which would have been a Date. Most likely, I would have used unix epoch ints to avoid all the string allocations