On May 18, 2010, at 0:33 , Kenton Varda wrote:
What if you did a fast scan of the bytes first to see if any are non- ASCII? Maybe only do this fast scan if the data is short enough to fit in L1 cache?

I didn't try this exact idea, but my guess is that it may not be a win: to get "fast" access to the char[] in the string, you need to copy them into a separate char[] array. If you are doing this much work, you might as well encode them into UTF-8 while you are at it.

Conclusion: 10% performance win for ASCII (garbage collection savings); no win for general UTF-8 text. Not worth it for protocol buffers, but I'll try digging into the decoding.


The approach I found worked the best:

1. Copy the string into a pre-allocated and re-used char[] array. This is needed since the JDK does not permit access to the String's char[] ,to enforce immutability. This is a performance "loss" VS the JDK, which can access the char[] directly.

2. Encode into a pre-allocated byte[] array. This will completely handle short strings. For long strings, you end up needing to allocate additional temporary space. This is "better" than the JDK, which allocates a new temporary buffer = 4 * str.length().

3. Allocate the final byte[] array, and System.arraycopy into it. This is the same as the JDK.

Conclusion: This is only better than the JDK in that it reduces allocation and garbage collection. It is worse than the JDK because it requires a copy from the String into another char[]. On my tests with ASCII-only data, it ends up ~10% faster. In my tests with UTF-8 data, it ends up about the same speed. In other words: this probably isn't worth it for Protocol Buffers: this is a small performance improvement, but complicates the code significantly.

However: For applications that can encode the string directly to the output buffer, this custom code can be significantly faster. However, since protocol buffers needs to encode to another buffer first to get the string length, this


I may spend some time poking around at string *decoding*, because there we should be able to decode directly from the input buffer, saving a copy and an allocation of a temporary byte[] array. Unclear if this will actually be significantly faster, but it might be slightly faster.

Evan

--
Evan Jones
http://evanjones.ca/

--
You received this message because you are subscribed to the Google Groups "Protocol 
Buffers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/protobuf?hl=en.

Reply via email to