Live data from Hacker News

Show HN: High-speed UTF-8 validation in Rust

github.com

21–30 of 48 posts

Re: Show HN: High-speed UTF-8 validation in Rust

#21
post #17

How does this compare, speed-wise, to the UTF-8 validation done in simdjson?

Check the benchmarks section (https://github.com/rusticstuff/simdutf8#Benchmarks), second table. simdutf8 is up to 28 % faster on my Comet Lake CPU. However with pure ASCII clang does something magical with simdjson and it beats my implementation by a lot. GCC-compiled simdjson is slower all around except for a few outliers with short byte sequences.

The algorithm is the one from simdjson, the main difference is that it uses an extra step in the beginning to align reads to the SIMD block size.

Re: Show HN: High-speed UTF-8 validation in Rust

#22

Does Rust compile code that can be used/called from other languages with an FFI? That to me is always one of the persistent advantages of C, I don't have to fully understand how compile machine code works on a technical level, but there are lots of different languages that let me use C libraries in their own language runtimes. It would be great to have things like high-performance unicode handling with consistent sem…

Yes, from the python side of things there are tools like py03 that make integrating rust into python code really painless.

I have a sql parsing library (shameless plug) that is 50x faster than any other python implementation, it is just a super simple wrapper around a rust crate.

https://github.com/wseaton/sqloxide

Re: Show HN: High-speed UTF-8 validation in Rust

#23

Does Rust compile code that can be used/called from other languages with an FFI? That to me is always one of the persistent advantages of C, I don't have to fully understand how compile machine code works on a technical level, but there are lots of different languages that let me use C libraries in their own language runtimes. It would be great to have things like high-performance unicode handling with consistent sem…

Yes, Rust natively can expose C ffi functions (for example).

The https://cxx.rs/ project is also a major crate for C++ interoperability.

Re: Show HN: High-speed UTF-8 validation in Rust

#24

One flavour I would expect to be valuable that isn't present here is this: Process the input (as quickly as possible) and never fail, but replace each invalid sequence of bytes with U+FFFD (bytes 0xEF 0xBF 0xBD).

One major problem with this: you can’t do it in place. Invalid byte sequences could be 1–4 bytes long, but U+FFFD is exactly three bytes long.

There're still faster approaches than naïve and probably common "copy valid byte sequences one by one into a resizable result buffer". For instance, scan through the input bytes all at once, keeping track of position and length of valid sequences, then memcopy each valid sequence into a preallocated buffer.

Edit: Although, it looks like Rust's std already does this, except for preallocating an exactly correct size result buffer: https://doc.rust-lang.org/src/alloc/string.rs.html#538

Re: Show HN: High-speed UTF-8 validation in Rust

#25
post #18

I was wonder about what the ARM/M1 support for simd like instructions are. It seems like it will be a while for these simd packages to be as performant on ARM. Is this correct?

ARM has it's own SIMD instruction sets (NEON and SVE) but the intrinsics have yet to be stabilized in Rust, so the Rust SIMD ecosystem is x86-centric for now.

The plan is for Rust to eventually have a portable SIMD abstraction built into the standard library to reduce the need for CPU-specific code.

Re: Show HN: High-speed UTF-8 validation in Rust

#26

Earlier quoted context omitted.

One major problem with this: you can’t do it in place. Invalid byte sequences could be 1–4 bytes long, but U+FFFD is exactly three bytes long.

There're still faster approaches than naïve and probably common "copy valid byte sequences one by one into a resizable result buffer". For instance, scan through the input bytes all at once, keeping track of position and length of valid sequences, then memcopy each valid sequence into a preallocated buffer. Edit: Although, it looks like Rust's std already does this, except for preallocating an exactly correct size re…

> preallocating an exactly correct size result buffer

Looks like it just uses the size of the original slice. If the average broken chunk is less than three bytes (maybe quite common?) then it'll have to grow the buffer, at least doubling it.

  >> let bytestring = b"foobar\xcc";
  >> bytestring.len()
  7
  >> let cleaned = String::from_utf8_lossy(bytestring).into_owned();
  >> cleaned.len()
  9
  >> cleaned.capacity()
  14

Re: Show HN: High-speed UTF-8 validation in Rust

#27
I find it interesting that with the state of rust SIMD many implementations just opted for reimplementing the code multiple times for each intrinsic (SSE, Neon, AVX, etc). One would think that one of the generic libraries (faster, simdeez, packed_simd) would start to see widespread use, but they all seem to have issues that have prevented adoption.

Re: Show HN: High-speed UTF-8 validation in Rust

#28
> The implementation is similar to the one in simdjson except that it aligns reads to the block size of the SIMD extension, which leads to better peak performance compared to the implementation in simdjson.

I didn't really understand this part. Aligned to what? to the cache line? SIMD always reads the block size. Unless I am missing something here.

Re: Show HN: High-speed UTF-8 validation in Rust

#29

> The implementation is similar to the one in simdjson except that it aligns reads to the block size of the SIMD extension, which leads to better peak performance compared to the implementation in simdjson. I didn't really understand this part. Aligned to what? to the cache line? SIMD always reads the block size. Unless I am missing something here.

I read it as "to the width of the SIMD registers" which I have seen in other quick scanners, but did not read the code here.

Re: Show HN: High-speed UTF-8 validation in Rust

#30

I find it interesting that with the state of rust SIMD many implementations just opted for reimplementing the code multiple times for each intrinsic (SSE, Neon, AVX, etc). One would think that one of the generic libraries (faster, simdeez, packed_simd) would start to see widespread use, but they all seem to have issues that have prevented adoption.

The various SIMD ISAs are different enough from eachother that you really want a custom implementation per ISA for perf reasons. Particularly if you're doing something off the beaten path like this rather than cranking through some vector math.
Post reply on HN