Skip to content

Commit dac8b31

Browse files
committed
Decode primitive types directly, without intermediate INode
Fix TSize (de)coding on a way there. This improves performance from: ``` BenchmarkDecode<TFlatStructLite> 24437 ns 24433 ns 29036 items_per_second=40.9277k/s BenchmarkDecode<TFlatStructHeavy> 24807 ns 24804 ns 29581 items_per_second=40.3154k/s BenchmarkDecode<TDeepStructLite> 88384 ns 88365 ns 7578 items_per_second=11.3167k/s BenchmarkDecode<TDeepStructHeavy> 42440 ns 42432 ns 16215 items_per_second=23.5672k/s ``` To: ``` BenchmarkDecode<TFlatStructLite> 10463 ns 10461 ns 67494 items_per_second=95.5953k/s BenchmarkDecode<TFlatStructHeavy> 10816 ns 10814 ns 66032 items_per_second=92.4694k/s BenchmarkDecode<TDeepStructLite> 72614 ns 72602 ns 9776 items_per_second=13.7737k/s BenchmarkDecode<TDeepStructHeavy> 26924 ns 26919 ns 26204 items_per_second=37.1486k/s ``` Part 1 of [https://nda.ya.ru/t/E9Ji-1bm7Gwv6c](https://nda.ya.ru/t/3w3MLYZB7Gwv6d commit_hash:de01ea3b3e667f0e090bf3c61df79726917a6ebd
1 parent 5a2a778 commit dac8b31

File tree

8 files changed

+86
-28
lines changed

8 files changed

+86
-28
lines changed

yt/yt/core/ya.make

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ IF (NOT OPENSOURCE AND OS_LINUX)
405405
benchmarks
406406
bus/benchmarks
407407
yson/benchmark
408+
ytree/benchmarks
408409
)
409410
ENDIF()
410411

yt/yt/core/ytree/serialize.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "serialize.h"
22

3-
#include "size.h"
43
#include "tree_visitor.h"
54

65
#include <yt/yt/core/misc/protobuf_helpers.h>
@@ -175,13 +174,6 @@ void Serialize(IInputStream& input, IYsonConsumer* consumer)
175174
Serialize(TYsonInput(&input), consumer);
176175
}
177176

178-
// TSize
179-
void Serialize(const TSize& value, NYson::IYsonConsumer* consumer)
180-
{
181-
Serialize(value.Underlying(), consumer);
182-
}
183-
184-
185177
// TStatisticPath.
186178
void Serialize(const NStatisticPath::TStatisticPath& path, IYsonConsumer* consumer)
187179
{
@@ -369,21 +361,6 @@ void Deserialize(TGuid& value, INodePtr node)
369361
value = TGuid::FromString(node->AsString()->GetValue());
370362
}
371363

372-
// TSize
373-
void Deserialize(TSize& value, INodePtr node)
374-
{
375-
if (node->GetType() == ENodeType::Int64) {
376-
value = TSize(node->AsInt64()->GetValue());
377-
} else if (node->GetType() == ENodeType::Uint64) {
378-
value = TSize(CheckedIntegralCast<i64>(node->AsUint64()->GetValue()));
379-
} else if (node->GetType() == ENodeType::String) {
380-
value = TSize::FromString(node->AsString()->GetValue());
381-
} else {
382-
THROW_ERROR_EXCEPTION("Cannot parse TSize value from %Qlv",
383-
node->GetType());
384-
}
385-
}
386-
387364
// TStatisticPath.
388365
void Deserialize(NStatisticPath::TStatisticPath& value, INodePtr node)
389366
{

yt/yt/core/ytree/serialize.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,6 @@ void Serialize(
180180
template <class T, class TTag>
181181
void Serialize(const TStrongTypedef<T, TTag>& value, NYson::IYsonConsumer* consumer);
182182

183-
void Serialize(const TSize& value, NYson::IYsonConsumer* consumer);
184-
185183
void Serialize(const NStatisticPath::TStatisticPath& path, NYson::IYsonConsumer* consumer);
186184

187185
////////////////////////////////////////////////////////////////////////////////
@@ -301,8 +299,6 @@ void Deserialize(
301299
template <class T, class TTag>
302300
void Deserialize(TStrongTypedef<T, TTag>& value, INodePtr node);
303301

304-
void Deserialize(TSize& value, INodePtr node);
305-
306302
void Deserialize(NStatisticPath::TStatisticPath& path, INodePtr node);
307303

308304
////////////////////////////////////////////////////////////////////////////////

yt/yt/core/ytree/size.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "size.h"
22

33
#include <yt/yt/core/misc/error.h>
4+
#include <yt/yt/core/ytree/convert.h>
45

56
#include <util/string/cast.h>
67

@@ -67,6 +68,44 @@ TSize TSize::FromString(TStringBuf serializedValue)
6768

6869
////////////////////////////////////////////////////////////////////////////////
6970

71+
void Serialize(const TSize& value, NYson::IYsonConsumer* consumer)
72+
{
73+
Serialize(value.Underlying(), consumer);
74+
}
75+
76+
void Deserialize(TSize& value, INodePtr node)
77+
{
78+
if (node->GetType() == ENodeType::Int64) {
79+
value = TSize(node->AsInt64()->GetValue());
80+
} else if (node->GetType() == ENodeType::Uint64) {
81+
value = TSize(CheckedIntegralCast<i64>(node->AsUint64()->GetValue()));
82+
} else if (node->GetType() == ENodeType::String) {
83+
value = TSize::FromString(node->AsString()->GetValue());
84+
} else {
85+
THROW_ERROR_EXCEPTION("Cannot parse TSize value from %Qlv",
86+
node->GetType());
87+
}
88+
}
89+
90+
void Deserialize(TSize& value, NYson::TYsonPullParserCursor* cursor)
91+
{
92+
if ((*cursor)->GetType() == NYson::EYsonItemType::Int64Value) {
93+
value = TSize((*cursor)->UncheckedAsInt64());
94+
cursor->Next();
95+
} else if ((*cursor)->GetType() == NYson::EYsonItemType::Uint64Value) {
96+
value = TSize(CheckedIntegralCast<i64>((*cursor)->UncheckedAsUint64()));
97+
cursor->Next();
98+
} else if ((*cursor)->GetType() == NYson::EYsonItemType::StringValue) {
99+
value = TSize::FromString((*cursor)->UncheckedAsString());
100+
cursor->Next();
101+
} else {
102+
THROW_ERROR_EXCEPTION("Cannot parse TSize value from %Qlv",
103+
(*cursor)->GetType());
104+
}
105+
}
106+
107+
////////////////////////////////////////////////////////////////////////////////
108+
70109
} // namespace NYT::NYTree
71110

72111
////////////////////////////////////////////////////////////////////////////////

yt/yt/core/ytree/size.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "public.h"
44

5+
#include <yt/yt/core/yson/public.h>
6+
57
namespace NYT::NYTree {
68

79
////////////////////////////////////////////////////////////////////////////////
@@ -41,6 +43,12 @@ class TSize
4143

4244
////////////////////////////////////////////////////////////////////////////////
4345

46+
void Serialize(const TSize& value, NYson::IYsonConsumer* consumer);
47+
void Deserialize(TSize& value, INodePtr node);
48+
void Deserialize(TSize& value, NYson::TYsonPullParserCursor* cursor);
49+
50+
////////////////////////////////////////////////////////////////////////////////
51+
4452
} // namespace NYT::NYTree
4553

4654
#define YTREE_SIZE_INL_H_

yt/yt/core/ytree/unittests/size_ut.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include <yt/yt/core/ytree/size.h>
44

5+
#include <yt/yt/core/ytree/convert.h>
6+
57
namespace NYT::NYTree {
68
namespace {
79

@@ -207,6 +209,34 @@ TEST(TYTreeSizeTest, FromStringBoundaryCases)
207209
EXPECT_THROW(DeserializeString("-10E"), std::exception);
208210
}
209211

212+
template <class T>
213+
TSize ConvertTroughYsonString(T&& t, NYson::EYsonFormat format)
214+
{
215+
return NYTree::ConvertTo<TSize>(NYson::ConvertToYsonString(std::forward<T>(t), format));
216+
}
217+
218+
TEST(TYTreeSizeTest, ConvertFromYsonString)
219+
{
220+
EXPECT_EQ(1, ConvertTroughYsonString(1, NYson::EYsonFormat::Binary));
221+
EXPECT_EQ(2, ConvertTroughYsonString("2", NYson::EYsonFormat::Text));
222+
EXPECT_EQ(3000, ConvertTroughYsonString("3K", NYson::EYsonFormat::Pretty));
223+
EXPECT_EQ(4 * 1024 * 1024, ConvertTroughYsonString("4Mi", NYson::EYsonFormat::Binary));
224+
}
225+
226+
template <class T>
227+
TSize ConvertTroughNode(T&& t)
228+
{
229+
return NYTree::ConvertTo<TSize>(NYTree::ConvertToNode(NYson::ConvertToYsonString(std::forward<T>(t))));
230+
}
231+
232+
TEST(TYTreeSizeTest, ConvertFromNode)
233+
{
234+
EXPECT_EQ(1, ConvertTroughNode(1));
235+
EXPECT_EQ(2, ConvertTroughNode("2"));
236+
EXPECT_EQ(3000, ConvertTroughNode("3K"));
237+
EXPECT_EQ(4 * 1024 * 1024, ConvertTroughNode("4Mi"));
238+
}
239+
210240
////////////////////////////////////////////////////////////////////////////////
211241

212242
} // namespace

yt/yt/core/ytree/yson_struct_detail-inl.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ template <CNodePtr TNodePtr>
120120
struct TYsonSourceTraits<TNodePtr>
121121
{
122122
static constexpr bool IsValid = true;
123+
static constexpr bool IsPullParser = false;
123124

124125
static INodePtr AsNode(TNodePtr& source)
125126
{
@@ -163,6 +164,7 @@ template <>
163164
struct TYsonSourceTraits<NYson::TYsonPullParserCursor*>
164165
{
165166
static constexpr bool IsValid = true;
167+
static constexpr bool IsPullParser = true;
166168

167169
static INodePtr AsNode(NYson::TYsonPullParserCursor*& source)
168170
{
@@ -240,7 +242,11 @@ void LoadFromSource(
240242
using TTraits = TYsonSourceTraits<TSource>;
241243

242244
try {
243-
Deserialize(parameter, TTraits::AsNode(source));
245+
if constexpr (TTraits::IsPullParser && NYson::ArePullParserDeserializable<T>()) {
246+
Deserialize(parameter, source);
247+
} else {
248+
Deserialize(parameter, TTraits::AsNode(source));
249+
}
244250
} catch (const std::exception& ex) {
245251
THROW_ERROR_EXCEPTION("Error reading parameter %v", pathGetter())
246252
<< ex;

yt/yt/core/ytree/yson_struct_detail.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ template <class T>
2121
struct TYsonSourceTraits
2222
{
2323
static constexpr bool IsValid = false;
24+
static constexpr bool IsPullParser = false;
2425

2526
static INodePtr AsNode(T& source)
2627
requires false;

0 commit comments

Comments
 (0)