diff options
| author | mat <github@matdoes.dev> | 2023-03-24 20:09:31 +0000 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2023-03-24 20:09:31 +0000 |
| commit | ac680d39f23f0fe004970fb9e48ca9a60437f607 (patch) | |
| tree | a92ae68ef6c6867f29be9ca49475439612791d60 | |
| parent | 4b387c320c126d2db69ec6f2dc1a610a58928a2e (diff) | |
| download | azalea-drasl-ac680d39f23f0fe004970fb9e48ca9a60437f607.tar.xz | |
random nbt improvements
| -rwxr-xr-x | azalea-nbt/benches/compare.rs | 4 | ||||
| -rwxr-xr-x | azalea-nbt/benches/nbt.rs | 46 | ||||
| -rwxr-xr-x | azalea-nbt/src/encode.rs | 162 |
3 files changed, 100 insertions, 112 deletions
diff --git a/azalea-nbt/benches/compare.rs b/azalea-nbt/benches/compare.rs index 23e133da..139a8b65 100755 --- a/azalea-nbt/benches/compare.rs +++ b/azalea-nbt/benches/compare.rs @@ -79,9 +79,9 @@ pub fn bench_read_file(filename: &str, c: &mut Criterion) { } fn bench(c: &mut Criterion) { - // bench_read_file("tests/bigtest.nbt", c); + bench_read_file("tests/bigtest.nbt", c); // bench_read_file("tests/simple_player.dat", c); - // bench_read_file("tests/complex_player.dat", c); + bench_read_file("tests/complex_player.dat", c); // bench_read_file("tests/level.dat", c); // bench_read_file("tests/stringtest.nbt", c); // bench_read_file("tests/inttest.nbt", c); diff --git a/azalea-nbt/benches/nbt.rs b/azalea-nbt/benches/nbt.rs index a219a46d..60f620b5 100755 --- a/azalea-nbt/benches/nbt.rs +++ b/azalea-nbt/benches/nbt.rs @@ -29,33 +29,33 @@ fn bench_file(filename: &str, c: &mut Criterion) { group.throughput(Throughput::Bytes(decoded_src.len() as u64)); - // group.bench_function("Decode", |b| { - // b.iter(|| { - // black_box(Nbt::read(&mut decoded_src_stream).unwrap()); - // decoded_src_stream.set_position(0); - // }) - // }); - - // group.bench_function("Encode", |b| { - // b.iter(|| { - // nbt.write(&mut black_box(Vec::new())); - // }) - // }); + group.bench_function("Decode", |b| { + b.iter(|| { + black_box(Nbt::read(&mut decoded_src_stream).unwrap()); + decoded_src_stream.set_position(0); + }) + }); - group.bench_function("Get", |b| { + group.bench_function("Encode", |b| { b.iter(|| { - let level = nbt - .as_compound() - .unwrap() - .get("Level") - .unwrap() - .as_compound() - .unwrap(); - for (k, _) in level.iter() { - black_box(level.get(black_box(k))); - } + nbt.write(&mut black_box(Vec::new())); }) }); + + // group.bench_function("Get", |b| { + // b.iter(|| { + // let level = nbt + // .as_compound() + // .unwrap() + // .get("Level") + // .unwrap() + // .as_compound() + // .unwrap(); + // for (k, _) in level.iter() { + // black_box(level.get(black_box(k))); + // } + // }) + // }); group.finish(); } diff --git a/azalea-nbt/src/encode.rs b/azalea-nbt/src/encode.rs index f5195327..7912eabb 100755 --- a/azalea-nbt/src/encode.rs +++ b/azalea-nbt/src/encode.rs @@ -5,13 +5,13 @@ use flate2::write::{GzEncoder, ZlibEncoder}; use packed_simd_2::{i32x16, i32x2, i32x4, i32x8, i64x2, i64x4, i64x8}; use std::io::Write; -#[inline(always)] +#[inline] fn write_string(writer: &mut impl Write, string: &NbtString) { writer.write_u16::<BE>(string.len() as u16).unwrap(); writer.write_all(string.as_bytes()).unwrap(); } -#[inline(always)] +#[inline] fn write_compound(writer: &mut impl Write, value: &NbtCompound, end_tag: bool) { for (key, tag) in value.iter() { writer.write_u8(tag.id()).unwrap(); @@ -61,7 +61,7 @@ fn write_compound(writer: &mut impl Write, value: &NbtCompound, end_tag: bool) { } } -#[inline(always)] +#[inline] fn write_list(writer: &mut impl Write, value: &NbtList) { writer.write_u8(value.id()).unwrap(); match value { @@ -80,82 +80,8 @@ fn write_list(writer: &mut impl Write, value: &NbtList) { writer.write_i16::<BE>(v).unwrap(); } } - NbtList::Int(l) => { - writer.write_i32::<BE>(l.len() as i32).unwrap(); - // flip the bits to big endian with simd - let l = l.as_slice(); - let mut position = 0; - // x16 - while l.len() - position >= 16 { - let l = unsafe { i32x16::from_slice_unaligned_unchecked(&l[position..]) }; - l.to_be(); - let l = unsafe { std::mem::transmute::<i32x16, [u8; 64]>(l) }; - writer.write_all(&l).unwrap(); - position += 16; - } - // x8 - if l.len() - position >= 8 { - let l = unsafe { i32x8::from_slice_unaligned_unchecked(&l[position..]) }; - l.to_be(); - let l = unsafe { std::mem::transmute::<i32x8, [u8; 32]>(l) }; - writer.write_all(&l).unwrap(); - position += 8; - } - // x4 - if l.len() - position >= 4 { - let l = unsafe { i32x4::from_slice_unaligned_unchecked(&l[position..]) }; - l.to_be(); - let l = unsafe { std::mem::transmute::<i32x4, [u8; 16]>(l) }; - writer.write_all(&l).unwrap(); - position += 4; - } - // x2 - if l.len() - position >= 2 { - let l = unsafe { i32x2::from_slice_unaligned_unchecked(&l[position..]) }; - l.to_be(); - let l = unsafe { std::mem::transmute::<i32x2, [u8; 8]>(l) }; - writer.write_all(&l).unwrap(); - position += 2; - } - // x1 ... just a normal write_i32 - if l.len() - position >= 1 { - writer.write_i32::<BE>(l[position]).unwrap(); - } - } - NbtList::Long(l) => { - writer.write_i32::<BE>(l.len() as i32).unwrap(); - // flip the bits to big endian with simd - let l = l.as_slice(); - let mut position = 0; - // x16 - while l.len() - position >= 8 { - let l = unsafe { i64x8::from_slice_unaligned_unchecked(&l[position..]) }; - l.to_be(); - let l = unsafe { std::mem::transmute::<i64x8, [u8; 64]>(l) }; - writer.write_all(&l).unwrap(); - position += 8; - } - // x4 - if l.len() - position >= 4 { - let l = unsafe { i64x4::from_slice_unaligned_unchecked(&l[position..]) }; - l.to_be(); - let l = unsafe { std::mem::transmute::<i64x4, [u8; 32]>(l) }; - writer.write_all(&l).unwrap(); - position += 4; - } - // x2 - if l.len() - position >= 2 { - let l = unsafe { i64x2::from_slice_unaligned_unchecked(&l[position..]) }; - l.to_be(); - let l = unsafe { std::mem::transmute::<i64x2, [u8; 16]>(l) }; - writer.write_all(&l).unwrap(); - position += 2; - } - // x1 ... just a normal write_i32 - if l.len() - position >= 1 { - writer.write_i64::<BE>(l[position]).unwrap(); - } - } + NbtList::Int(l) => write_int_array(writer, l), + NbtList::Long(l) => write_long_array(writer, l), NbtList::Float(l) => { writer.write_i32::<BE>(l.len() as i32).unwrap(); for &v in l { @@ -214,18 +140,80 @@ fn write_byte_array(writer: &mut impl Write, value: &[u8]) { } #[inline] -fn write_int_array(writer: &mut impl Write, value: &Vec<i32>) { - writer.write_u32::<BE>(value.len() as u32).unwrap(); - for &int in value { - writer.write_i32::<BE>(int).unwrap(); +fn write_int_array(writer: &mut impl Write, l: &[i32]) { + writer.write_i32::<BE>(l.len() as i32).unwrap(); + // flip the bits to big endian with simd + let mut position = 0; + // x16 + while l.len() - position >= 16 { + let l = unsafe { i32x16::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i32x16, [u8; 64]>(l) }; + writer.write_all(&l).unwrap(); + position += 16; + } + // x8 + if l.len() - position >= 8 { + let l = unsafe { i32x8::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i32x8, [u8; 32]>(l) }; + writer.write_all(&l).unwrap(); + position += 8; + } + // x4 + if l.len() - position >= 4 { + let l = unsafe { i32x4::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i32x4, [u8; 16]>(l) }; + writer.write_all(&l).unwrap(); + position += 4; + } + // x2 + if l.len() - position >= 2 { + let l = unsafe { i32x2::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i32x2, [u8; 8]>(l) }; + writer.write_all(&l).unwrap(); + position += 2; + } + // x1 ... just a normal write_i32 + if l.len() - position >= 1 { + writer.write_i32::<BE>(l[position]).unwrap(); } } #[inline] -fn write_long_array(writer: &mut impl Write, value: &Vec<i64>) { - writer.write_u32::<BE>(value.len() as u32).unwrap(); - for &long in value { - writer.write_i64::<BE>(long).unwrap(); +fn write_long_array(writer: &mut impl Write, l: &[i64]) { + writer.write_i32::<BE>(l.len() as i32).unwrap(); + // flip the bits to big endian with simd + let mut position = 0; + // x16 + while l.len() - position >= 8 { + let l = unsafe { i64x8::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i64x8, [u8; 64]>(l) }; + writer.write_all(&l).unwrap(); + position += 8; + } + // x4 + if l.len() - position >= 4 { + let l = unsafe { i64x4::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i64x4, [u8; 32]>(l) }; + writer.write_all(&l).unwrap(); + position += 4; + } + // x2 + if l.len() - position >= 2 { + let l = unsafe { i64x2::from_slice_unaligned_unchecked(&l[position..]) }; + l.to_be(); + let l = unsafe { std::mem::transmute::<i64x2, [u8; 16]>(l) }; + writer.write_all(&l).unwrap(); + position += 2; + } + // x1 ... just a normal write_i32 + if l.len() - position >= 1 { + writer.write_i64::<BE>(l[position]).unwrap(); } } |
