Skip to content

Commit 40b0c6f

Browse files
committed
Use extend_from_slice from fastwrite for faster writing into a
buffer.
1 parent 7592d31 commit 40b0c6f

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

src/codegen.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::ptr;
12
use std::io::Write;
23
use std::num::FpCategory;
34
use JsonValue;
@@ -201,9 +202,8 @@ impl DumpGenerator {
201202
impl Generator for DumpGenerator {
202203
type T = Vec<u8>;
203204

204-
#[inline(always)]
205205
fn write(&mut self, slice: &[u8]) {
206-
self.code.extend_from_slice(slice)
206+
extend_from_slice(&mut self.code, slice);
207207
}
208208

209209
#[inline(always)]
@@ -247,7 +247,7 @@ impl Generator for PrettyGenerator {
247247

248248
#[inline(always)]
249249
fn write(&mut self, slice: &[u8]) {
250-
self.code.extend_from_slice(slice)
250+
extend_from_slice(&mut self.code, slice);
251251
}
252252

253253
#[inline(always)]
@@ -306,3 +306,25 @@ impl<'a, W> Generator for WriterGenerator<'a, W> where W: Write {
306306
self.writer.write_all(&[min]).unwrap();
307307
}
308308
}
309+
310+
// From: https://github.com/dtolnay/fastwrite/blob/master/src/lib.rs#L68
311+
//
312+
// LLVM is not able to lower `Vec::extend_from_slice` into a memcpy, so this
313+
// helps eke out that last bit of performance.
314+
#[inline]
315+
fn extend_from_slice(dst: &mut Vec<u8>, src: &[u8]) {
316+
let dst_len = dst.len();
317+
let src_len = src.len();
318+
319+
dst.reserve(src_len);
320+
321+
unsafe {
322+
// We would have failed if `reserve` overflowed
323+
dst.set_len(dst_len + src_len);
324+
325+
ptr::copy_nonoverlapping(
326+
src.as_ptr(),
327+
dst.as_mut_ptr().offset(dst_len as isize),
328+
src_len);
329+
}
330+
}

0 commit comments

Comments
 (0)