Skip to content

Commit a6d00db

Browse files
jckingcopybara-github
authored andcommitted
Optimize BytesValueInputStream by avoiding std::visit
PiperOrigin-RevId: 991073619
1 parent 9602b67 commit a6d00db

2 files changed

Lines changed: 30 additions & 72 deletions

File tree

‎common/values/bytes_value_input_stream.h‎

Lines changed: 26 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,12 @@
2121
#include <cstddef>
2222
#include <cstdint>
2323
#include <limits>
24-
#include <new>
24+
#include <utility>
25+
#include <variant>
2526

26-
#include "absl/base/attributes.h"
27-
#include "absl/base/nullability.h"
2827
#include "absl/log/absl_check.h"
2928
#include "absl/strings/cord.h"
3029
#include "absl/strings/string_view.h"
31-
#include "absl/types/variant.h"
32-
#include "absl/utility/utility.h"
3330
#include "common/internal/byte_string.h"
3431
#include "common/values/bytes_value.h"
3532
#include "google/protobuf/io/zero_copy_stream.h"
@@ -39,51 +36,20 @@ namespace cel {
3936

4037
class BytesValueInputStream final : public google::protobuf::io::ZeroCopyInputStream {
4138
public:
42-
explicit BytesValueInputStream(
43-
const BytesValue* absl_nonnull value ABSL_ATTRIBUTE_LIFETIME_BOUND) {
44-
Construct(value);
45-
}
46-
47-
~BytesValueInputStream() override { AsVariant().~variant(); }
39+
explicit BytesValueInputStream(const BytesValue& value) { Construct(value); }
4840

4941
bool Next(const void** data, int* size) override {
50-
return absl::visit(
51-
[&data, &size](auto& alternative) -> bool {
52-
return alternative.stream.Next(data, size);
53-
},
54-
AsVariant());
42+
return stream_->Next(data, size);
5543
}
5644

57-
void BackUp(int count) override {
58-
absl::visit(
59-
[&count](auto& alternative) -> void {
60-
alternative.stream.BackUp(count);
61-
},
62-
AsVariant());
63-
}
45+
void BackUp(int count) override { stream_->BackUp(count); }
6446

65-
bool Skip(int count) override {
66-
return absl::visit(
67-
[&count](auto& alternative) -> bool {
68-
return alternative.stream.Skip(count);
69-
},
70-
AsVariant());
71-
}
47+
bool Skip(int count) override { return stream_->Skip(count); }
7248

73-
int64_t ByteCount() const override {
74-
return absl::visit(
75-
[](const auto& alternative) -> int64_t {
76-
return alternative.stream.ByteCount();
77-
},
78-
AsVariant());
79-
}
49+
int64_t ByteCount() const override { return stream_->ByteCount(); }
8050

8151
bool ReadCord(absl::Cord* cord, int count) override {
82-
return absl::visit(
83-
[&cord, &count](auto& alternative) -> bool {
84-
return alternative.stream.ReadCord(cord, count);
85-
},
86-
AsVariant());
52+
return stream_->ReadCord(cord, count);
8753
}
8854

8955
private:
@@ -93,54 +59,45 @@ class BytesValueInputStream final : public google::protobuf::io::ZeroCopyInputSt
9359
google::protobuf::io::ArrayInputStream stream;
9460
};
9561
struct CordStream {
96-
explicit CordStream(const absl::Cord& cord)
97-
: cord(cord), stream(&this->cord) {}
62+
explicit CordStream(absl::Cord cord)
63+
: cord(std::move(cord)), stream(&this->cord) {}
9864

9965
absl::Cord cord;
10066
google::protobuf::io::CordInputStream stream;
10167
};
102-
using Variant = absl::variant<ArrayStream, CordStream>;
103-
104-
void Construct(const BytesValue* absl_nonnull value) {
105-
ABSL_DCHECK(value != nullptr);
68+
using Variant = std::variant<std::monostate, ArrayStream, CordStream>;
10669

107-
switch (value->value_.GetKind()) {
70+
void Construct(const BytesValue& value) {
71+
switch (value.value_.GetKind()) {
10872
case common_internal::ByteStringKind::kSmall:
109-
Construct(value->value_.GetSmall());
73+
small_ = value.value_.rep_.small;
74+
Construct(absl::string_view(small_.data, small_.size));
11075
break;
11176
case common_internal::ByteStringKind::kMedium:
112-
Construct(value->value_.GetMedium());
77+
Construct(value.value_.GetMedium());
11378
break;
11479
case common_internal::ByteStringKind::kLarge:
115-
Construct(value->value_.GetLarge());
80+
Construct(value.value_.GetLarge());
11681
break;
11782
}
11883
}
11984

12085
void Construct(absl::string_view value) {
12186
ABSL_DCHECK_LE(value.size(),
12287
static_cast<size_t>(std::numeric_limits<int>::max()));
123-
::new (static_cast<void*>(&impl_[0]))
124-
Variant(absl::in_place_type<ArrayStream>, value.data(),
125-
static_cast<int>(value.size()));
126-
}
127-
128-
void Construct(const absl::Cord& value) {
129-
::new (static_cast<void*>(&impl_[0]))
130-
Variant(absl::in_place_type<CordStream>, value);
131-
}
132-
133-
void Destruct() { AsVariant().~variant(); }
134-
135-
Variant& AsVariant() ABSL_ATTRIBUTE_LIFETIME_BOUND {
136-
return *std::launder(reinterpret_cast<Variant*>(&impl_[0]));
88+
stream_ =
89+
&variant_
90+
.emplace<ArrayStream>(value.data(), static_cast<int>(value.size()))
91+
.stream;
13792
}
13893

139-
const Variant& AsVariant() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
140-
return *std::launder(reinterpret_cast<const Variant*>(&impl_[0]));
94+
void Construct(absl::Cord value) {
95+
stream_ = &variant_.emplace<CordStream>(std::move(value)).stream;
14196
}
14297

143-
alignas(Variant) char impl_[sizeof(Variant)];
98+
google::protobuf::io::ZeroCopyInputStream* stream_;
99+
common_internal::SmallByteStringRep small_;
100+
Variant variant_;
144101
};
145102

146103
} // namespace cel

‎common/values/bytes_value_test.cc‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ TEST_F(BytesValueTest, Comparison) {
170170

171171
TEST_F(BytesValueTest, StringInputStream) {
172172
BytesValue value = BytesValue::WrapUnsafe("foo");
173-
BytesValueInputStream stream(&value);
173+
BytesValueInputStream stream(value);
174174
const void* data;
175175
int size;
176176
absl::Cord cord;
@@ -185,8 +185,9 @@ TEST_F(BytesValueTest, StringInputStream) {
185185
}
186186

187187
TEST_F(BytesValueTest, CordInputStream) {
188-
BytesValue value = BytesValue::From(absl::Cord("foo"), arena());
189-
BytesValueInputStream stream(&value);
188+
absl::Cord value_cord("foo");
189+
BytesValue value = BytesValue::WrapUnsafe(&value_cord);
190+
BytesValueInputStream stream(value);
190191
const void* data;
191192
int size;
192193
absl::Cord cord;

0 commit comments

Comments
 (0)