大概实现了一个统一测试(
This commit is contained in:
parent
8a37f72d6a
commit
f8a001e38d
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -3,5 +3,7 @@
|
|||||||
"crates/shen-nbt1/Cargo.toml",
|
"crates/shen-nbt1/Cargo.toml",
|
||||||
"crates/shen-nbt2/Cargo.toml",
|
"crates/shen-nbt2/Cargo.toml",
|
||||||
"crates/shen-nbt3/Cargo.toml",
|
"crates/shen-nbt3/Cargo.toml",
|
||||||
|
"crates/shen-nbt4/Cargo.toml",
|
||||||
|
"crates/nbt-test/Cargo.toml",
|
||||||
]
|
]
|
||||||
}
|
}
|
21
crates/nbt-test/Cargo.toml
Normal file
21
crates/nbt-test/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
[package]
|
||||||
|
name = "nbt-test"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
debug = []
|
||||||
|
core_debug = []
|
||||||
|
internal_opt = []
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
fastnbt = "2.4.4"
|
||||||
|
shen-nbt1 = { path = "../shen-nbt1" }
|
||||||
|
shen-nbt2 = { path = "../shen-nbt2" }
|
||||||
|
shen-nbt3 = { path = "../shen-nbt3" }
|
||||||
|
shen-nbt4 = { path = "../shen-nbt4" }
|
||||||
|
|
@ -1,41 +1,23 @@
|
|||||||
#![feature(buf_read_has_data_left)]
|
|
||||||
|
|
||||||
use crate::data::Reader;
|
|
||||||
use std::io::Read;
|
|
||||||
|
|
||||||
mod data;
|
|
||||||
mod read;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, nbt!");
|
||||||
// sleep 1s
|
// sleep 1s
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
println!("====== small test ======");
|
||||||
small_read_test();
|
small_read_test();
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
println!("====== big test ======");
|
||||||
big_read_test();
|
big_read_test();
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
println!("====== cli test ======");
|
||||||
cli_read_test();
|
cli_read_test();
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// bincode-org/bincode: A binary encoder / decoder implementation in Rust.
|
|
||||||
// https://github.com/bincode-org/bincode
|
|
||||||
|
|
||||||
fn cli_read_test() {
|
fn cli_read_test() {
|
||||||
let mut buff: Vec<u8> = Vec::new();
|
let mut args = std::env::args();
|
||||||
// 从 CLI 读取文件名
|
// 如果有, 取出
|
||||||
let filename = std::env::args().nth(1).unwrap();
|
if let Some(arg) = args.nth(1) {
|
||||||
// 打开文件
|
let data = std::fs::read(arg).unwrap();
|
||||||
{
|
read_test(data);
|
||||||
let mut file = std::fs::File::open(filename).unwrap();
|
} else {
|
||||||
// 转为 &[u8]
|
println!("Usage: cargo run --release -- <file>");
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
|
||||||
println!("file size: {}", file.metadata().unwrap().len());
|
|
||||||
_ = file.read_to_end(&mut buff).unwrap();
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
|
||||||
}
|
}
|
||||||
// 读取数据
|
|
||||||
read_test(buff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn small_read_test() {
|
fn small_read_test() {
|
||||||
@ -156,44 +138,68 @@ fn big_read_test() {
|
|||||||
read_test(data.to_vec());
|
read_test(data.to_vec());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_test(data: Vec<u8>) {
|
|
||||||
let len = data.len();
|
macro_rules! test_lib {
|
||||||
|
($func: block, $name: expr, $len: expr) => {
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
let start_time = std::time::Instant::now();
|
||||||
|
$func
|
||||||
|
let end_time = std::time::Instant::now();
|
||||||
|
println!("=== {} ===", $name);
|
||||||
|
print!("time: {:?}", end_time - start_time);
|
||||||
|
println!(" speed: {:?} (bytes/sec)", $len as f64 / (end_time - start_time).as_secs_f64());
|
||||||
|
println!("{:?} (kb/sec)", $len as f64 / (end_time - start_time).as_secs_f64() / 1024.0);
|
||||||
|
println!(
|
||||||
|
"{:?} (mb/sec)",
|
||||||
|
$len as f64 / (end_time - start_time).as_secs_f64() / 1024.0 / 1024.0
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"{:?} (gb/sec)",
|
||||||
|
$len as f64 / (end_time - start_time).as_secs_f64() / 1024.0 / 1024.0 / 1024.0
|
||||||
|
);
|
||||||
|
#[cfg(feature = "core_debug")]
|
||||||
|
println!("nbt_data: {:#?}", nbt_data);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_test(in_data: Vec<u8>) {
|
||||||
|
let len = in_data.len();
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
println!("data: {:?}", data);
|
println!("data: {:?}", data);
|
||||||
let cursor: Reader = std::io::Cursor::new(data.as_slice());
|
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
let data = in_data.clone();
|
||||||
let start_time = std::time::Instant::now();
|
let data2 = in_data.clone();
|
||||||
|
let data3 = in_data.clone();
|
||||||
let nbt_data = data::NbtItem::try_from(cursor).unwrap();
|
let data4 = in_data.clone();
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
let end_time = std::time::Instant::now();
|
test_lib!(
|
||||||
println!("===local nbt===");
|
{
|
||||||
println!("time: {:?}", end_time - start_time);
|
let cursor: shen_nbt1::data::Reader = std::io::Cursor::new(data.as_slice());
|
||||||
println!("speed: {:?} (bytes/sec)", len as f64 / (end_time - start_time).as_secs_f64());
|
let _nbt_data = shen_nbt1::data::NbtItem::try_from(cursor).unwrap();
|
||||||
println!("{:?} (kb/sec)", len as f64 / (end_time - start_time).as_secs_f64() / 1024.0);
|
}, "nbt v1", len
|
||||||
println!(
|
|
||||||
"{:?} (mb/sec)",
|
|
||||||
len as f64 / (end_time - start_time).as_secs_f64() / 1024.0 / 1024.0
|
|
||||||
);
|
|
||||||
#[cfg(feature = "core_debug")]
|
|
||||||
println!("nbt_data: {:#?}", nbt_data);
|
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
|
||||||
let start_time = std::time::Instant::now();
|
|
||||||
|
|
||||||
let nbt_data: fastnbt::Value = fastnbt::from_bytes(data.as_slice()).unwrap();
|
|
||||||
|
|
||||||
let end_time = std::time::Instant::now();
|
|
||||||
println!("===fastnbt===");
|
|
||||||
println!("time: {:?}", end_time - start_time);
|
|
||||||
println!("speed: {:?} (bytes/sec)", len as f64 / (end_time - start_time).as_secs_f64());
|
|
||||||
println!("{:?} (kb/sec)", len as f64 / (end_time - start_time).as_secs_f64() / 1024.0);
|
|
||||||
println!(
|
|
||||||
"{:?} (mb/sec)",
|
|
||||||
len as f64 / (end_time - start_time).as_secs_f64() / 1024.0 / 1024.0
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "core_debug")]
|
test_lib!(
|
||||||
println!("nbt_data: {:#?}", nbt_data);
|
{
|
||||||
|
let _nbt_data = shen_nbt2::Value::from_vec(data2);
|
||||||
|
}, "nbt v2", len
|
||||||
|
);
|
||||||
|
|
||||||
|
test_lib!(
|
||||||
|
{
|
||||||
|
let _nbt_data = shen_nbt3::Value::from_vec(data3);
|
||||||
|
}, "nbt v3", len
|
||||||
|
);
|
||||||
|
|
||||||
|
test_lib!(
|
||||||
|
{
|
||||||
|
let _nbt_data = shen_nbt4::Value::from_vec(data4);
|
||||||
|
}, "nbt v4", len
|
||||||
|
);
|
||||||
|
|
||||||
|
test_lib!(
|
||||||
|
{
|
||||||
|
let _nbt_data: fastnbt::Value = fastnbt::from_bytes(data.as_slice()).unwrap();
|
||||||
|
}, "fastnbt", len
|
||||||
|
);
|
||||||
}
|
}
|
@ -1,13 +1,10 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nbt-rust"
|
name = "shen-nbt1"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
fastnbt = "2.4.4"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
debug = []
|
debug = []
|
||||||
|
4
crates/shen-nbt1/src/lib.rs
Normal file
4
crates/shen-nbt1/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#![feature(buf_read_has_data_left)]
|
||||||
|
|
||||||
|
pub mod data;
|
||||||
|
pub mod read;
|
@ -182,7 +182,7 @@ pub enum Value<'value> {
|
|||||||
/// 12
|
/// 12
|
||||||
LongArray(Vec<i64>),
|
LongArray(Vec<i64>),
|
||||||
/// 9
|
/// 9
|
||||||
List(Vec<Value>),
|
List(Vec<Value<'value>>),
|
||||||
/// 10
|
/// 10
|
||||||
Compound(Vec<(String, Value<'value>)>),
|
Compound(Vec<(String, Value<'value>)>),
|
||||||
}
|
}
|
||||||
@ -216,31 +216,37 @@ impl<'value> Value<'value> {
|
|||||||
1 => {
|
1 => {
|
||||||
let raw_data = data.read_bytes(length as usize);
|
let raw_data = data.read_bytes(length as usize);
|
||||||
let list = raw_reading::slice_as_byte_array(raw_data.as_slice());
|
let list = raw_reading::slice_as_byte_array(raw_data.as_slice());
|
||||||
|
let list = list.iter().map(|x| Self::Byte(*x)).collect();
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
let raw_data = data.read_bytes(length as usize * 2);
|
let raw_data = data.read_bytes(length as usize * 2);
|
||||||
let list = raw_reading::slice_as_short_array(raw_data.as_slice()).unwrap();
|
let list = raw_reading::slice_as_short_array(raw_data.as_slice()).unwrap();
|
||||||
|
let list = list.iter().map(|x| Self::Short(*x)).collect();
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
let raw_data = data.read_bytes(length as usize * 4);
|
let raw_data = data.read_bytes(length as usize * 4);
|
||||||
let list = raw_reading::slice_as_int_array(raw_data.as_slice()).unwrap();
|
let list = raw_reading::slice_as_int_array(raw_data.as_slice()).unwrap();
|
||||||
|
let list = list.iter().map(|x| Self::Int(*x)).collect();
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
}
|
}
|
||||||
4 => {
|
4 => {
|
||||||
let raw_data = data.read_bytes(length as usize * 8);
|
let raw_data = data.read_bytes(length as usize * 8);
|
||||||
let list = raw_reading::slice_as_long_array(raw_data.as_slice()).unwrap();
|
let list = raw_reading::slice_as_long_array(raw_data.as_slice()).unwrap();
|
||||||
|
let list = list.iter().map(|x| Self::Long(*x)).collect();
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
}
|
}
|
||||||
5 => {
|
5 => {
|
||||||
let raw_data = data.read_bytes(length as usize * 4);
|
let raw_data = data.read_bytes(length as usize * 4);
|
||||||
let list = raw_reading::slice_as_float_array(raw_data.as_slice()).unwrap();
|
let list = raw_reading::slice_as_float_array(raw_data.as_slice()).unwrap();
|
||||||
|
let list = list.iter().map(|x| Self::Float(*x)).collect();
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
}
|
}
|
||||||
6 => {
|
6 => {
|
||||||
let raw_data = data.read_bytes(length as usize * 8);
|
let raw_data = data.read_bytes(length as usize * 8);
|
||||||
let list = raw_reading::slice_as_double_array(raw_data.as_slice()).unwrap();
|
let list = raw_reading::slice_as_double_array(raw_data.as_slice()).unwrap();
|
||||||
|
let list = list.iter().map(|x| Self::Double(*x)).collect();
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
}
|
}
|
||||||
7 => {
|
7 => {
|
||||||
@ -249,6 +255,7 @@ impl<'value> Value<'value> {
|
|||||||
let length = data.read_int();
|
let length = data.read_int();
|
||||||
let raw_data = data.read_bytes(length as usize);
|
let raw_data = data.read_bytes(length as usize);
|
||||||
let value = raw_reading::slice_as_byte_array(raw_data.as_slice());
|
let value = raw_reading::slice_as_byte_array(raw_data.as_slice());
|
||||||
|
let value = Self::ByteArray(value);
|
||||||
list.push(value);
|
list.push(value);
|
||||||
}
|
}
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
@ -260,6 +267,7 @@ impl<'value> Value<'value> {
|
|||||||
let value = std::str::from_utf8(data.read_bytes(length as usize).as_slice())
|
let value = std::str::from_utf8(data.read_bytes(length as usize).as_slice())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
let value = Self::String(value.into());
|
||||||
list.push(value);
|
list.push(value);
|
||||||
}
|
}
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
@ -270,6 +278,7 @@ impl<'value> Value<'value> {
|
|||||||
for _ in 0..length {
|
for _ in 0..length {
|
||||||
let inner_list = Self::read_list(data);
|
let inner_list = Self::read_list(data);
|
||||||
let value = inner_list.into_list().unwrap();
|
let value = inner_list.into_list().unwrap();
|
||||||
|
let value = Self::List(value);
|
||||||
list.push(value);
|
list.push(value);
|
||||||
}
|
}
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
@ -279,6 +288,7 @@ impl<'value> Value<'value> {
|
|||||||
for _ in 0..length {
|
for _ in 0..length {
|
||||||
let inner_compound = Self::read_compound(data);
|
let inner_compound = Self::read_compound(data);
|
||||||
let value = inner_compound.into_compound().unwrap();
|
let value = inner_compound.into_compound().unwrap();
|
||||||
|
let value = Self::Compound(value);
|
||||||
list.push(value);
|
list.push(value);
|
||||||
}
|
}
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
@ -289,6 +299,7 @@ impl<'value> Value<'value> {
|
|||||||
let length = data.read_int();
|
let length = data.read_int();
|
||||||
let raw_data = data.read_bytes(length as usize * 4);
|
let raw_data = data.read_bytes(length as usize * 4);
|
||||||
let value = raw_reading::slice_as_int_array(raw_data.as_slice()).unwrap();
|
let value = raw_reading::slice_as_int_array(raw_data.as_slice()).unwrap();
|
||||||
|
let value = Self::IntArray(value);
|
||||||
list.push(value);
|
list.push(value);
|
||||||
}
|
}
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
@ -299,6 +310,7 @@ impl<'value> Value<'value> {
|
|||||||
let length = data.read_int();
|
let length = data.read_int();
|
||||||
let raw_data = data.read_bytes(length as usize * 8);
|
let raw_data = data.read_bytes(length as usize * 8);
|
||||||
let value = raw_reading::slice_as_long_array(raw_data.as_slice()).unwrap();
|
let value = raw_reading::slice_as_long_array(raw_data.as_slice()).unwrap();
|
||||||
|
let value = Self::LongArray(value);
|
||||||
list.push(value);
|
list.push(value);
|
||||||
}
|
}
|
||||||
Self::List(list)
|
Self::List(list)
|
||||||
@ -409,7 +421,7 @@ impl<'value> Value<'value> {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn as_list(&self) -> Option<&ListContent> {
|
pub fn as_list(&self) -> Option<&Vec<Value<'value>>> {
|
||||||
match self {
|
match self {
|
||||||
Self::List(value) => Some(value),
|
Self::List(value) => Some(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -440,7 +452,7 @@ impl<'value> Value<'value> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn into_list(self) -> Option<ListContent<'value>> {
|
pub fn into_list(self) -> Option<Vec<Value<'value>>> {
|
||||||
match self {
|
match self {
|
||||||
Self::List(value) => Some(value),
|
Self::List(value) => Some(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
Loading…
Reference in New Issue
Block a user