Skip to content

Commit 2409c18

Browse files
lalitbutpillacijothomas
authored
Box complex types in AnyValue enum (Improve perf by 10%, and size reduction by ~60%) (#1993)
Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
1 parent fe10ab1 commit 2409c18

File tree

6 files changed

+107
-44
lines changed

6 files changed

+107
-44
lines changed

opentelemetry-appender-log/src/lib.rs

+32-23
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ mod any_value {
429429
}
430430

431431
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
432-
Ok(Some(AnyValue::Bytes(v.to_owned())))
432+
Ok(Some(AnyValue::Bytes(Box::new(v.to_owned()))))
433433
}
434434

435435
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
@@ -557,7 +557,7 @@ mod any_value {
557557
}
558558

559559
fn end(self) -> Result<Self::Ok, Self::Error> {
560-
Ok(Some(AnyValue::ListAny(self.value)))
560+
Ok(Some(AnyValue::ListAny(Box::new(self.value))))
561561
}
562562
}
563563

@@ -578,7 +578,7 @@ mod any_value {
578578
}
579579

580580
fn end(self) -> Result<Self::Ok, Self::Error> {
581-
Ok(Some(AnyValue::ListAny(self.value)))
581+
Ok(Some(AnyValue::ListAny(Box::new(self.value))))
582582
}
583583
}
584584

@@ -599,7 +599,7 @@ mod any_value {
599599
}
600600

601601
fn end(self) -> Result<Self::Ok, Self::Error> {
602-
Ok(Some(AnyValue::ListAny(self.value)))
602+
Ok(Some(AnyValue::ListAny(Box::new(self.value))))
603603
}
604604
}
605605

@@ -621,8 +621,11 @@ mod any_value {
621621

622622
fn end(self) -> Result<Self::Ok, Self::Error> {
623623
Ok(Some(AnyValue::Map({
624-
let mut variant = HashMap::new();
625-
variant.insert(Key::from(self.variant), AnyValue::ListAny(self.value));
624+
let mut variant = Box::<HashMap<Key, AnyValue>>::default();
625+
variant.insert(
626+
Key::from(self.variant),
627+
AnyValue::ListAny(Box::new(self.value)),
628+
);
626629
variant
627630
})))
628631
}
@@ -664,7 +667,7 @@ mod any_value {
664667
}
665668

666669
fn end(self) -> Result<Self::Ok, Self::Error> {
667-
Ok(Some(AnyValue::Map(self.value)))
670+
Ok(Some(AnyValue::Map(Box::new(self.value))))
668671
}
669672
}
670673

@@ -688,7 +691,7 @@ mod any_value {
688691
}
689692

690693
fn end(self) -> Result<Self::Ok, Self::Error> {
691-
Ok(Some(AnyValue::Map(self.value)))
694+
Ok(Some(AnyValue::Map(Box::new(self.value))))
692695
}
693696
}
694697

@@ -713,8 +716,8 @@ mod any_value {
713716

714717
fn end(self) -> Result<Self::Ok, Self::Error> {
715718
Ok(Some(AnyValue::Map({
716-
let mut variant = HashMap::new();
717-
variant.insert(Key::from(self.variant), AnyValue::Map(self.value));
719+
let mut variant = Box::<HashMap<Key, AnyValue>>::default();
720+
variant.insert(Key::from(self.variant), AnyValue::Map(Box::new(self.value)));
718721
variant
719722
})))
720723
}
@@ -1025,13 +1028,17 @@ mod tests {
10251028
assert_eq!(AnyValue::Int(42), get("some_value").unwrap());
10261029

10271030
assert_eq!(
1028-
AnyValue::ListAny(vec![AnyValue::Int(1), AnyValue::Int(1), AnyValue::Int(1)]),
1031+
AnyValue::ListAny(Box::new(vec![
1032+
AnyValue::Int(1),
1033+
AnyValue::Int(1),
1034+
AnyValue::Int(1)
1035+
])),
10291036
get("slice_value").unwrap()
10301037
);
10311038

10321039
assert_eq!(
10331040
AnyValue::Map({
1034-
let mut map = HashMap::new();
1041+
let mut map = Box::<HashMap<Key, AnyValue>>::default();
10351042

10361043
map.insert(Key::from("a"), AnyValue::Int(1));
10371044
map.insert(Key::from("b"), AnyValue::Int(1));
@@ -1044,7 +1051,7 @@ mod tests {
10441051

10451052
assert_eq!(
10461053
AnyValue::Map({
1047-
let mut map = HashMap::new();
1054+
let mut map = Box::<HashMap<Key, AnyValue>>::default();
10481055

10491056
map.insert(Key::from("a"), AnyValue::Int(1));
10501057
map.insert(Key::from("b"), AnyValue::Int(1));
@@ -1056,7 +1063,11 @@ mod tests {
10561063
);
10571064

10581065
assert_eq!(
1059-
AnyValue::ListAny(vec![AnyValue::Int(1), AnyValue::Int(1), AnyValue::Int(1)]),
1066+
AnyValue::ListAny(Box::new(vec![
1067+
AnyValue::Int(1),
1068+
AnyValue::Int(1),
1069+
AnyValue::Int(1)
1070+
])),
10601071
get("tuple_value").unwrap()
10611072
);
10621073

@@ -1071,7 +1082,7 @@ mod tests {
10711082

10721083
map.insert(Key::from("Newtype"), AnyValue::Int(42));
10731084

1074-
map
1085+
Box::new(map)
10751086
}),
10761087
get("newtype_variant_value").unwrap()
10771088
);
@@ -1082,18 +1093,16 @@ mod tests {
10821093

10831094
map.insert(
10841095
Key::from("Struct"),
1085-
AnyValue::Map({
1096+
AnyValue::Map(Box::new({
10861097
let mut map = HashMap::new();
1087-
10881098
map.insert(Key::from("a"), AnyValue::Int(1));
10891099
map.insert(Key::from("b"), AnyValue::Int(1));
10901100
map.insert(Key::from("c"), AnyValue::Int(1));
1091-
10921101
map
1093-
}),
1102+
})),
10941103
);
10951104

1096-
map
1105+
Box::new(map)
10971106
}),
10981107
get("struct_variant_value").unwrap()
10991108
);
@@ -1104,14 +1113,14 @@ mod tests {
11041113

11051114
map.insert(
11061115
Key::from("Tuple"),
1107-
AnyValue::ListAny(vec![
1116+
AnyValue::ListAny(Box::new(vec![
11081117
AnyValue::Int(1),
11091118
AnyValue::Int(1),
11101119
AnyValue::Int(1),
1111-
]),
1120+
])),
11121121
);
11131122

1114-
map
1123+
Box::new(map)
11151124
}),
11161125
get("tuple_variant_value").unwrap()
11171126
);

opentelemetry-proto/src/transform/logs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub mod tonic {
4949
})
5050
.collect(),
5151
}),
52-
LogsAnyValue::Bytes(v) => Value::BytesValue(v),
52+
LogsAnyValue::Bytes(v) => Value::BytesValue(*v),
5353
}
5454
}
5555
}

opentelemetry-sdk/benches/log.rs

+21-13
Original file line numberDiff line numberDiff line change
@@ -151,74 +151,82 @@ fn criterion_benchmark(c: &mut Criterion) {
151151
logger.emit(log_record);
152152
});
153153

154-
let bytes = AnyValue::Bytes(vec![25u8, 30u8, 40u8]);
154+
let bytes = AnyValue::Bytes(Box::new(vec![25u8, 30u8, 40u8]));
155155
log_benchmark_group(c, "simple-log-with-bytes", |logger| {
156156
let mut log_record = logger.create_log_record();
157157
log_record.set_body("simple log".into());
158158
log_record.add_attribute("testbytes", bytes.clone());
159159
logger.emit(log_record);
160160
});
161161

162-
let bytes = AnyValue::Bytes(vec![
162+
let bytes = AnyValue::Bytes(Box::new(vec![
163163
25u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8,
164164
30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8,
165165
40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8,
166166
30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8,
167167
40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8,
168168
30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8, 30u8, 40u8,
169-
]);
169+
]));
170170
log_benchmark_group(c, "simple-log-with-a-lot-of-bytes", |logger| {
171171
let mut log_record = logger.create_log_record();
172172
log_record.set_body("simple log".into());
173173
log_record.add_attribute("testbytes", bytes.clone());
174174
logger.emit(log_record);
175175
});
176176

177-
let vec_any_values = AnyValue::ListAny(vec![AnyValue::Int(25), "test".into(), true.into()]);
177+
let vec_any_values = AnyValue::ListAny(Box::new(vec![
178+
AnyValue::Int(25),
179+
"test".into(),
180+
true.into(),
181+
]));
178182
log_benchmark_group(c, "simple-log-with-vec-any-value", |logger| {
179183
let mut log_record = logger.create_log_record();
180184
log_record.set_body("simple log".into());
181185
log_record.add_attribute("testvec", vec_any_values.clone());
182186
logger.emit(log_record);
183187
});
184188

185-
let vec_any_values = AnyValue::ListAny(vec![AnyValue::Int(25), "test".into(), true.into()]);
186-
let vec_any_values = AnyValue::ListAny(vec![
189+
let vec_any_values = AnyValue::ListAny(Box::new(vec![
190+
AnyValue::Int(25),
191+
"test".into(),
192+
true.into(),
193+
]));
194+
let vec_any_values = AnyValue::ListAny(Box::new(vec![
187195
AnyValue::Int(25),
188196
"test".into(),
189197
true.into(),
190198
vec_any_values,
191-
]);
199+
]));
192200
log_benchmark_group(c, "simple-log-with-inner-vec-any-value", |logger| {
193201
let mut log_record = logger.create_log_record();
194202
log_record.set_body("simple log".into());
195203
log_record.add_attribute("testvec", vec_any_values.clone());
196204
logger.emit(log_record);
197205
});
198206

199-
let map_any_values = AnyValue::Map(HashMap::from([
207+
let map_any_values = AnyValue::Map(Box::new(HashMap::from([
200208
("testint".into(), 2.into()),
201209
("testdouble".into(), 2.2.into()),
202210
("teststring".into(), "test".into()),
203-
]));
211+
])));
204212
log_benchmark_group(c, "simple-log-with-map-any-value", |logger| {
205213
let mut log_record = logger.create_log_record();
206214
log_record.set_body("simple log".into());
207215
log_record.add_attribute("testmap", map_any_values.clone());
208216
logger.emit(log_record);
209217
});
210218

211-
let map_any_values = AnyValue::Map(HashMap::from([
219+
let map_any_values = AnyValue::Map(Box::new(HashMap::from([
212220
("testint".into(), 2.into()),
213221
("testdouble".into(), 2.2.into()),
214222
("teststring".into(), "test".into()),
215-
]));
216-
let map_any_values = AnyValue::Map(HashMap::from([
223+
])));
224+
let map_any_values = AnyValue::Map(Box::new(HashMap::from([
217225
("testint".into(), 2.into()),
218226
("testdouble".into(), 2.2.into()),
219227
("teststring".into(), "test".into()),
220228
("testmap".into(), map_any_values),
221-
]));
229+
])));
222230
log_benchmark_group(c, "simple-log-with-inner-map-any-value", |logger| {
223231
let mut log_record = logger.create_log_record();
224232
log_record.set_body("simple log".into());

opentelemetry-stdout/src/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ impl From<opentelemetry::logs::AnyValue> for Value {
168168
})
169169
.collect(),
170170
),
171-
opentelemetry::logs::AnyValue::Bytes(b) => Value::BytesValue(b),
171+
opentelemetry::logs::AnyValue::Bytes(b) => Value::BytesValue(*b),
172172
}
173173
}
174174
}

opentelemetry/CHANGELOG.md

+46
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,52 @@
22

33
## vNext
44

5+
- **BREAKING** [#1993](https://github.com/open-telemetry/opentelemetry-rust/pull/1993) Box complex types in AnyValue enum
6+
Before:
7+
```rust
8+
#[derive(Debug, Clone, PartialEq)]
9+
pub enum AnyValue {
10+
/// An integer value
11+
Int(i64),
12+
/// A double value
13+
Double(f64),
14+
/// A string value
15+
String(StringValue),
16+
/// A boolean value
17+
Boolean(bool),
18+
/// A byte array
19+
Bytes(Vec<u8>),
20+
/// An array of `Any` values
21+
ListAny(Vec<AnyValue>),
22+
/// A map of string keys to `Any` values, arbitrarily nested.
23+
Map(HashMap<Key, AnyValue>),
24+
}
25+
```
26+
27+
After:
28+
```rust
29+
#[derive(Debug, Clone, PartialEq)]
30+
pub enum AnyValue {
31+
/// An integer value
32+
Int(i64),
33+
/// A double value
34+
Double(f64),
35+
/// A string value
36+
String(StringValue),
37+
/// A boolean value
38+
Boolean(bool),
39+
/// A byte array
40+
Bytes(Box<Vec<u8>>),
41+
/// An array of `Any` values
42+
ListAny(Box<Vec<AnyValue>>),
43+
/// A map of string keys to `Any` values, arbitrarily nested.
44+
Map(Box<HashMap<Key, AnyValue>>),
45+
}
46+
```
47+
So the custom log appenders should box these types while adding them in message body, or
48+
attribute values. Similarly, the custom exporters should dereference these complex type values
49+
before serializing.
50+
551
## v0.24.0
652

753
- Add "metrics", "logs" to default features. With this, default feature list is

opentelemetry/src/logs/record.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ pub enum AnyValue {
5959
/// A boolean value
6060
Boolean(bool),
6161
/// A byte array
62-
Bytes(Vec<u8>),
62+
Bytes(Box<Vec<u8>>),
6363
/// An array of `Any` values
64-
ListAny(Vec<AnyValue>),
64+
ListAny(Box<Vec<AnyValue>>),
6565
/// A map of string keys to `Any` values, arbitrarily nested.
66-
Map(HashMap<Key, AnyValue>),
66+
Map(Box<HashMap<Key, AnyValue>>),
6767
}
6868

6969
macro_rules! impl_trivial_from {
@@ -98,17 +98,17 @@ impl_trivial_from!(bool, AnyValue::Boolean);
9898
impl<T: Into<AnyValue>> FromIterator<T> for AnyValue {
9999
/// Creates an [`AnyValue::ListAny`] value from a sequence of `Into<AnyValue>` values.
100100
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
101-
AnyValue::ListAny(iter.into_iter().map(Into::into).collect())
101+
AnyValue::ListAny(Box::new(iter.into_iter().map(Into::into).collect()))
102102
}
103103
}
104104

105105
impl<K: Into<Key>, V: Into<AnyValue>> FromIterator<(K, V)> for AnyValue {
106106
/// Creates an [`AnyValue::Map`] value from a sequence of key-value pairs
107107
/// that can be converted into a `Key` and `AnyValue` respectively.
108108
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
109-
AnyValue::Map(HashMap::from_iter(
109+
AnyValue::Map(Box::new(HashMap::from_iter(
110110
iter.into_iter().map(|(k, v)| (k.into(), v.into())),
111-
))
111+
)))
112112
}
113113
}
114114

0 commit comments

Comments
 (0)