1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

::with_capacity instead of ::new for vecs in nbt

This commit is contained in:
mat 2021-12-19 20:20:43 -06:00
parent 55c9f58219
commit f50cdfccfc
4 changed files with 22 additions and 17 deletions

View file

@ -1,5 +1,6 @@
use azalea_nbt::Tag; use azalea_nbt::Tag;
use criterion::{criterion_group, criterion_main, Criterion, Throughput}; use criterion::{criterion_group, criterion_main, Criterion, Throughput};
use flate2::read::GzDecoder;
use std::{ use std::{
fs::File, fs::File,
io::{self, Read, Seek, SeekFrom}, io::{self, Read, Seek, SeekFrom},
@ -10,18 +11,25 @@ fn bench_serialize(filename: &str, c: &mut Criterion) {
let mut contents = Vec::new(); let mut contents = Vec::new();
file.read_to_end(&mut contents).unwrap(); file.read_to_end(&mut contents).unwrap();
let mut src = std::io::Cursor::new(&contents[..]); let mut src = std::io::Cursor::new(&contents[..]);
// decode the original src so most of the time isn't spent on unzipping
let mut decoded_src_decoder = GzDecoder::new(&mut src);
let mut decoded_src = Vec::new();
decoded_src_decoder.read_to_end(&mut decoded_src).unwrap();
let mut decoded_src_stream = std::io::Cursor::new(decoded_src);
file.seek(SeekFrom::Start(0)).unwrap(); file.seek(SeekFrom::Start(0)).unwrap();
let nbt = Tag::read_gzip(&mut file).unwrap(); let nbt = Tag::read_gzip(&mut file).unwrap();
let mut group = c.benchmark_group(filename); let mut group = c.benchmark_group(filename);
group.throughput(Throughput::Bytes(contents.len() as u64)); group.throughput(Throughput::Bytes(contents.len() as u64));
group.bench_function("Deserialize As Blob", |b| { group.bench_function("Decode", |b| {
b.iter(|| { b.iter(|| {
src.seek(SeekFrom::Start(0)).unwrap(); decoded_src_stream.seek(SeekFrom::Start(0)).unwrap();
Tag::read_gzip(&mut src).unwrap(); Tag::read(&mut decoded_src_stream).unwrap();
}) })
}); });
group.bench_function("Serialize As Blob", |b| { group.bench_function("Encode", |b| {
b.iter(|| { b.iter(|| {
nbt.write(&mut io::sink()).unwrap(); nbt.write(&mut io::sink()).unwrap();
}) })
@ -31,9 +39,9 @@ fn bench_serialize(filename: &str, c: &mut Criterion) {
fn bench(c: &mut Criterion) { fn bench(c: &mut Criterion) {
bench_serialize("tests/bigtest.nbt", c); bench_serialize("tests/bigtest.nbt", c);
// bench_serialize::<data::PlayerData>("tests/simple_player.dat", c); // bench_serialize("tests/simple_player.dat", c);
// bench_serialize::<data::PlayerData>("tests/complex_player.dat", c); // bench_serialize("tests/complex_player.dat", c);
// bench_serialize::<data::Level>("tests/level.dat", c); bench_serialize("tests/level.dat", c);
} }
criterion_group!(benches, bench); criterion_group!(benches, bench);

View file

@ -28,7 +28,7 @@ impl Tag {
// integer (thus 4 bytes) // integer (thus 4 bytes)
7 => { 7 => {
let length = stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?; let length = stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?;
let mut bytes = Vec::new(); let mut bytes = Vec::with_capacity(length as usize);
for _ in 0..length { for _ in 0..length {
bytes.push(stream.read_i8().map_err(|_| Error::InvalidTag)?); bytes.push(stream.read_i8().map_err(|_| Error::InvalidTag)?);
} }
@ -39,7 +39,7 @@ impl Tag {
// string in bytes // string in bytes
8 => { 8 => {
let length = stream.read_u16::<BE>().map_err(|_| Error::InvalidTag)?; let length = stream.read_u16::<BE>().map_err(|_| Error::InvalidTag)?;
let mut bytes = Vec::new(); let mut bytes = Vec::with_capacity(length as usize);
for _ in 0..length { for _ in 0..length {
bytes.push(stream.read_u8().map_err(|_| Error::InvalidTag)?); bytes.push(stream.read_u8().map_err(|_| Error::InvalidTag)?);
} }
@ -56,7 +56,7 @@ impl Tag {
9 => { 9 => {
let type_id = stream.read_u8().map_err(|_| Error::InvalidTag)?; let type_id = stream.read_u8().map_err(|_| Error::InvalidTag)?;
let length = stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?; let length = stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?;
let mut list = Vec::new(); let mut list = Vec::with_capacity(length as usize);
for _ in 0..length { for _ in 0..length {
list.push(Tag::read_known(stream, type_id)?); list.push(Tag::read_known(stream, type_id)?);
} }
@ -64,7 +64,8 @@ impl Tag {
} }
// Effectively a list of a named tags. Order is not guaranteed. // Effectively a list of a named tags. Order is not guaranteed.
10 => { 10 => {
let mut map = HashMap::new(); // we default to capacity 4 because it'll probably not be empty
let mut map = HashMap::with_capacity(4);
loop { loop {
let tag_id = stream.read_u8().unwrap_or(0); let tag_id = stream.read_u8().unwrap_or(0);
if tag_id == 0 { if tag_id == 0 {
@ -84,7 +85,7 @@ impl Tag {
// integers. // integers.
11 => { 11 => {
let length = stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?; let length = stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?;
let mut ints = Vec::new(); let mut ints = Vec::with_capacity(length as usize);
for _ in 0..length { for _ in 0..length {
ints.push(stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?); ints.push(stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?);
} }
@ -94,7 +95,7 @@ impl Tag {
// integer (thus 4 bytes) and indicates the number of 8 byte longs. // integer (thus 4 bytes) and indicates the number of 8 byte longs.
12 => { 12 => {
let length = stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?; let length = stream.read_i32::<BE>().map_err(|_| Error::InvalidTag)?;
let mut longs = Vec::new(); let mut longs = Vec::with_capacity(length as usize);
for _ in 0..length { for _ in 0..length {
longs.push(stream.read_i64::<BE>().map_err(|_| Error::InvalidTag)?); longs.push(stream.read_i64::<BE>().map_err(|_| Error::InvalidTag)?);
} }

BIN
azalea-nbt/tests/level.dat Normal file

Binary file not shown.

View file

@ -1,8 +1,4 @@
use azalea_nbt::Tag; use azalea_nbt::Tag;
use flate2::{
read::{GzDecoder, ZlibDecoder},
write::{GzEncoder, ZlibEncoder},
};
use std::{ use std::{
collections::HashMap, collections::HashMap,
io::{Cursor, Read}, io::{Cursor, Read},