Skip to content
This repository was archived by the owner on Nov 27, 2022. It is now read-only.

Commit 28e4e1a

Browse files
authored
Update hecs, add to serialization benchmarks
Update hecs, add to serialization benchmarks
1 parent b2d7289 commit 28e4e1a

File tree

125 files changed

+8443
-2325
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+8443
-2325
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ serde = { version = "1.0", features = ["derive"] }
1414
rayon = "1.3"
1515
legion = "0.3"
1616
bevy_ecs = "0.3"
17-
hecs = "0.3"
17+
hecs = { version = "0.5", features = ["column-serialize", "row-serialize"] }
1818
shipyard = "0.4"
1919
specs = {version = "0.16.1", features = ["serde"] }
2020
specs-derive = "0.4.1"

benches/benchmarks.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ fn bench_serialize_text(c: &mut Criterion) {
171171
let mut bench = legion::serialize_text::Benchmark::new();
172172
b.iter(move || bench.run());
173173
});
174+
group.bench_function("hecs", |b| {
175+
let mut bench = hecs::serialize_text::Benchmark::new();
176+
b.iter(move || bench.run());
177+
});
174178
// group.bench_function("bevy", |b| {
175179
// let mut bench = bevy::serialize_text::Benchmark::new();
176180
// b.iter(move || bench.run());
@@ -183,6 +187,10 @@ fn bench_serialize_binary(c: &mut Criterion) {
183187
let mut bench = legion::serialize_binary::Benchmark::new();
184188
b.iter(move || bench.run());
185189
});
190+
group.bench_function("hecs", |b| {
191+
let mut bench = hecs::serialize_binary::Benchmark::new();
192+
b.iter(move || bench.run());
193+
});
186194
// group.bench_function("bevy", |b| {
187195
// let mut bench = bevy::serialize_text::Benchmark::new();
188196
// b.iter(move || bench.run());

src/hecs/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ pub mod frag_iter;
33
pub mod heavy_compute;
44
pub mod simple_insert;
55
pub mod simple_iter;
6+
pub mod serialize_binary;
7+
pub mod serialize_text;

src/hecs/serialize_binary.rs

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
use hecs::{serialize::column::*, *};
2+
use serde::{de::SeqAccess, ser::SerializeTuple, Deserialize, Serialize};
3+
4+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
5+
struct Transform([f32; 16]);
6+
7+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
8+
struct Position {
9+
x: f32,
10+
y: f32,
11+
z: f32,
12+
}
13+
14+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
15+
struct Rotation {
16+
x: f32,
17+
y: f32,
18+
z: f32,
19+
}
20+
21+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
22+
struct Velocity {
23+
x: f32,
24+
y: f32,
25+
z: f32,
26+
}
27+
28+
struct SerContext;
29+
30+
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
31+
enum ComponentId {
32+
Transform,
33+
Position,
34+
Rotation,
35+
Velocity,
36+
}
37+
38+
impl SerializeContext for SerContext {
39+
fn component_count(&self, archetype: &Archetype) -> usize {
40+
use std::any::TypeId;
41+
archetype
42+
.component_types()
43+
.filter(|&x| {
44+
x == TypeId::of::<Transform>()
45+
|| x == TypeId::of::<Position>()
46+
|| x == TypeId::of::<Rotation>()
47+
|| x == TypeId::of::<Velocity>()
48+
})
49+
.count()
50+
}
51+
52+
fn serialize_component_ids<S: SerializeTuple>(
53+
&mut self,
54+
archetype: &Archetype,
55+
out: &mut S,
56+
) -> Result<(), S::Error> {
57+
if archetype.has::<Transform>() {
58+
out.serialize_element(&ComponentId::Transform)?;
59+
}
60+
if archetype.has::<Position>() {
61+
out.serialize_element(&ComponentId::Position)?;
62+
}
63+
if archetype.has::<Rotation>() {
64+
out.serialize_element(&ComponentId::Rotation)?;
65+
}
66+
if archetype.has::<Velocity>() {
67+
out.serialize_element(&ComponentId::Velocity)?;
68+
}
69+
Ok(())
70+
}
71+
72+
fn serialize_components<S: SerializeTuple>(
73+
&mut self,
74+
archetype: &Archetype,
75+
out: &mut S,
76+
) -> Result<(), S::Error> {
77+
try_serialize::<Transform, _>(archetype, out)?;
78+
try_serialize::<Position, _>(archetype, out)?;
79+
try_serialize::<Rotation, _>(archetype, out)?;
80+
try_serialize::<Velocity, _>(archetype, out)?;
81+
Ok(())
82+
}
83+
}
84+
85+
struct DeContext {
86+
components: Vec<ComponentId>,
87+
}
88+
89+
impl DeserializeContext for DeContext {
90+
fn deserialize_component_ids<'de, A>(&mut self, mut seq: A) -> Result<ColumnBatchType, A::Error>
91+
where
92+
A: SeqAccess<'de>,
93+
{
94+
self.components.clear();
95+
let mut batch = ColumnBatchType::new();
96+
while let Some(id) = seq.next_element()? {
97+
match id {
98+
ComponentId::Transform => {
99+
batch.add::<Transform>();
100+
}
101+
ComponentId::Position => {
102+
batch.add::<Position>();
103+
}
104+
ComponentId::Rotation => {
105+
batch.add::<Rotation>();
106+
}
107+
ComponentId::Velocity => {
108+
batch.add::<Velocity>();
109+
}
110+
}
111+
self.components.push(id);
112+
}
113+
Ok(batch)
114+
}
115+
116+
fn deserialize_components<'de, A>(
117+
&mut self,
118+
entity_count: u32,
119+
mut seq: A,
120+
batch: &mut ColumnBatchBuilder,
121+
) -> Result<(), A::Error>
122+
where
123+
A: SeqAccess<'de>,
124+
{
125+
for &component in &self.components {
126+
match component {
127+
ComponentId::Transform => {
128+
deserialize_column::<Transform, _>(entity_count, &mut seq, batch)?;
129+
}
130+
ComponentId::Position => {
131+
deserialize_column::<Position, _>(entity_count, &mut seq, batch)?;
132+
}
133+
ComponentId::Rotation => {
134+
deserialize_column::<Rotation, _>(entity_count, &mut seq, batch)?;
135+
}
136+
ComponentId::Velocity => {
137+
deserialize_column::<Velocity, _>(entity_count, &mut seq, batch)?;
138+
}
139+
}
140+
}
141+
Ok(())
142+
}
143+
}
144+
145+
pub struct Benchmark(World);
146+
147+
impl Benchmark {
148+
pub fn new() -> Self {
149+
let mut world = World::new();
150+
151+
world.spawn_batch((0..1000).map(|_| {
152+
(
153+
Transform::default(),
154+
Position::default(),
155+
Rotation::default(),
156+
Velocity::default(),
157+
)
158+
}));
159+
160+
Self(world)
161+
}
162+
163+
pub fn run(&mut self) {
164+
let Self(world) = self;
165+
let mut encoded = Vec::new();
166+
serialize(
167+
&world,
168+
&mut SerContext,
169+
&mut bincode::Serializer::new(&mut encoded, bincode::options()),
170+
)
171+
.unwrap();
172+
deserialize(
173+
&mut DeContext {
174+
components: Vec::new(),
175+
},
176+
&mut bincode::Deserializer::from_slice(&encoded, bincode::options()),
177+
)
178+
.unwrap();
179+
}
180+
}

src/hecs/serialize_text.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
use hecs::{serialize::row::*, *};
2+
use serde::{de::MapAccess, ser::SerializeMap, Deserialize, Serialize};
3+
4+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
5+
struct Transform([f32; 16]);
6+
7+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
8+
struct Position {
9+
x: f32,
10+
y: f32,
11+
z: f32,
12+
}
13+
14+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
15+
struct Rotation {
16+
x: f32,
17+
y: f32,
18+
z: f32,
19+
}
20+
21+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
22+
struct Velocity {
23+
x: f32,
24+
y: f32,
25+
z: f32,
26+
}
27+
28+
struct SerContext;
29+
30+
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
31+
enum ComponentId {
32+
Transform,
33+
Position,
34+
Rotation,
35+
Velocity,
36+
}
37+
38+
impl SerializeContext for SerContext {
39+
fn serialize_entity<S: SerializeMap>(
40+
&mut self,
41+
entity: EntityRef<'_>,
42+
map: &mut S,
43+
) -> Result<(), S::Error> {
44+
try_serialize::<Transform, _, _>(&entity, &ComponentId::Transform, map)?;
45+
try_serialize::<Position, _, _>(&entity, &ComponentId::Position, map)?;
46+
try_serialize::<Rotation, _, _>(&entity, &ComponentId::Rotation, map)?;
47+
try_serialize::<Velocity, _, _>(&entity, &ComponentId::Velocity, map)?;
48+
Ok(())
49+
}
50+
}
51+
52+
struct DeContext;
53+
54+
impl DeserializeContext for DeContext {
55+
fn deserialize_entity<'de, M>(
56+
&mut self,
57+
mut map: M,
58+
entity: &mut EntityBuilder,
59+
) -> Result<(), M::Error>
60+
where
61+
M: MapAccess<'de>,
62+
{
63+
while let Some(key) = map.next_key()? {
64+
match key {
65+
ComponentId::Transform => {
66+
entity.add::<Transform>(map.next_value()?);
67+
}
68+
ComponentId::Position => {
69+
entity.add::<Position>(map.next_value()?);
70+
}
71+
ComponentId::Rotation => {
72+
entity.add::<Rotation>(map.next_value()?);
73+
}
74+
ComponentId::Velocity => {
75+
entity.add::<Velocity>(map.next_value()?);
76+
}
77+
}
78+
}
79+
Ok(())
80+
}
81+
}
82+
83+
pub struct Benchmark(World);
84+
85+
impl Benchmark {
86+
pub fn new() -> Self {
87+
let mut world = World::new();
88+
89+
world.spawn_batch((0..1000).map(|_| {
90+
(
91+
Transform::default(),
92+
Position::default(),
93+
Rotation::default(),
94+
Velocity::default(),
95+
)
96+
}));
97+
98+
Self(world)
99+
}
100+
101+
pub fn run(&mut self) {
102+
let Self(world) = self;
103+
let mut encoded = Vec::new();
104+
serialize(
105+
&world,
106+
&mut SerContext,
107+
&mut ron::Serializer::new(&mut encoded, None, false).unwrap(),
108+
)
109+
.unwrap();
110+
deserialize(
111+
&mut DeContext,
112+
&mut ron::Deserializer::from_bytes(&encoded).unwrap(),
113+
)
114+
.unwrap();
115+
}
116+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":7852978.849999998,"upper_bound":7880880.985714288},"point_estimate":7863751.142857144,"standard_error":7468.981744971249},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":7846428.571428572,"upper_bound":7849114.285714285},"point_estimate":7847878.571428571,"standard_error":674.48962169372},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4818.4499144547235,"upper_bound":8895.599842071533},"point_estimate":6586.9798830579275,"standard_error":1005.572768410693},"slope":null,"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":17750.056178514464,"upper_bound":124677.46342744156},"point_estimate":75299.81862345229,"standard_error":34496.96520104101}}
1+
{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1018603.4615741395,"upper_bound":1024336.695636737},"point_estimate":1021359.0072397925,"standard_error":1461.591076380341},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1015533.3333333334,"upper_bound":1020141.5290880504},"point_estimate":1017120.8333333333,"standard_error":1195.8414709883778},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":8064.277890041331,"upper_bound":14413.563727847895},"point_estimate":11521.203879727273,"standard_error":1538.276741282933},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1016514.2785071325,"upper_bound":1022444.3565449244},"point_estimate":1019403.7972513669,"standard_error":1518.4036531574177},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":11449.939192242102,"upper_bound":17449.551936190976},"point_estimate":14675.119674929852,"standard_error":1533.9571690766702}}

0 commit comments

Comments
 (0)