diff options
| author | thenewone <[email protected]> | 2025-08-04 20:25:02 +0300 | 
|---|---|---|
| committer | thenewone <[email protected]> | 2025-08-04 21:30:57 +0300 | 
| commit | 140e5db975aa31e2326abb3b5bd58a6e142075c6 (patch) | |
| tree | 48258c7ab5d06aea1a36cab4a568bd9f044394f4 | |
| parent | 77ae0a1260666d7ad2baf248ecd24200b337dd4d (diff) | |
Don't construct twice yson struct members of yson struct lite type
There is a serious problem of all yson structs: their members are
constructed twice when the yson struct is constructing: the first
time implicitly as common members, and the second time explicitly
right in yson struct constructor's body.
So if any yson struct A has a member of yson struct lite type B,
then per one A's construction the B will be constructed twice. If
in turn B has a member of yson struct lite type C then it will be
contructed two time per B's contruction and four times per A's
construction. The next level D will be constructed 8 times etc,
generally giving compexity of 2^N for construction of yson struct
lite chain of length N.
This patch solves the most common case when yson struct lite member
is declared as .Default() or .Otional(). In this case ther's no
need to construct the member the second time.
This gives improvement from:
```
BenchmarkDecode<TDeepStructLite>       88384 ns        88365 ns         7578 items_per_second=11.3167k/s
```
To:
```
BenchmarkDecode<TDeepStructLite>       35361 ns        35359 ns        19786 items_per_second=28.2814k/s
```
Part 3 of https://nda.ya.ru/t/E9Ji-1bm7Gwv6c
commit_hash:b8a3db2cdc4393bae38b7310047cc3fcd9b9a15c
| -rw-r--r-- | yt/yt/core/ytree/yson_struct-inl.h | 2 | ||||
| -rw-r--r-- | yt/yt/core/ytree/yson_struct.cpp | 6 | ||||
| -rw-r--r-- | yt/yt/core/ytree/yson_struct.h | 2 | ||||
| -rw-r--r-- | yt/yt/core/ytree/yson_struct_detail-inl.h | 8 | ||||
| -rw-r--r-- | yt/yt/core/ytree/yson_struct_detail.cpp | 4 | ||||
| -rw-r--r-- | yt/yt/core/ytree/yson_struct_detail.h | 9 | 
6 files changed, 16 insertions, 15 deletions
| diff --git a/yt/yt/core/ytree/yson_struct-inl.h b/yt/yt/core/ytree/yson_struct-inl.h index 9ef10db1b53..423d287f372 100644 --- a/yt/yt/core/ytree/yson_struct-inl.h +++ b/yt/yt/core/ytree/yson_struct-inl.h @@ -453,7 +453,7 @@ private: \      if (std::type_index(typeid(TStruct)) == this->FinalType_) { \          ::NYT::NYTree::TYsonStructRegistry::Get()->OnFinalCtorCalled(); \          if (!::NYT::NYTree::TYsonStructRegistry::Get()->InitializationInProgress()) { \ -            this->SetDefaults(); \ +            this->SetDefaults(/*dontSetLiteMembers*/ true); \          } \      } \ diff --git a/yt/yt/core/ytree/yson_struct.cpp b/yt/yt/core/ytree/yson_struct.cpp index e4a6b30df76..d3294f3754d 100644 --- a/yt/yt/core/ytree/yson_struct.cpp +++ b/yt/yt/core/ytree/yson_struct.cpp @@ -181,10 +181,10 @@ void TYsonStructBase::Postprocess(const std::function<NYPath::TYPath()>& pathGet      Meta_->PostprocessStruct(this, pathGetter);  } -void TYsonStructBase::SetDefaults() +void TYsonStructBase::SetDefaults(bool dontSetLiteMembers)  {      YT_VERIFY(Meta_); -    Meta_->SetDefaultsOfInitializedStruct(this); +    Meta_->SetDefaultsOfInitializedStruct(this, dontSetLiteMembers);  }  void TYsonStructBase::SaveParameter(const std::string& key, IYsonConsumer* consumer) const @@ -236,7 +236,7 @@ void TYsonStruct::InitializeRefCounted()  {      TYsonStructRegistry::Get()->OnFinalCtorCalled();      if (!TYsonStructRegistry::InitializationInProgress()) { -        SetDefaults(); +        SetDefaults(/*dontSetLiteMembers*/ true);      }  } diff --git a/yt/yt/core/ytree/yson_struct.h b/yt/yt/core/ytree/yson_struct.h index 7cceb5a2288..4cebefa3234 100644 --- a/yt/yt/core/ytree/yson_struct.h +++ b/yt/yt/core/ytree/yson_struct.h @@ -92,7 +92,7 @@ public:      void Postprocess(const std::function<NYPath::TYPath()>& pathGetter = {}); -    void SetDefaults(); +    void SetDefaults(bool dontSetLiteMembers = false);      void Save(NYson::IYsonConsumer* consumer) const; diff --git a/yt/yt/core/ytree/yson_struct_detail-inl.h b/yt/yt/core/ytree/yson_struct_detail-inl.h index d6ddccb63d1..0bdfa8a58da 100644 --- a/yt/yt/core/ytree/yson_struct_detail-inl.h +++ b/yt/yt/core/ytree/yson_struct_detail-inl.h @@ -929,11 +929,10 @@ void TYsonStructParameter<TValue>::PostprocessParameter(const TYsonStructBase* s  }  template <class TValue> -void TYsonStructParameter<TValue>::SetDefaultsInitialized(TYsonStructBase* self) +void TYsonStructParameter<TValue>::SetDefaultsInitialized(TYsonStructBase* self, bool dontSetLiteMembers)  { -    TValue& value = FieldAccessor_->GetValue(self); - -    if (DefaultCtor_) { +    if (DefaultCtor_ && !(std::is_base_of_v<TYsonStructLite, TValue> && dontSetLiteMembers && DefaultIsDefaultConstruction_)) { +        TValue& value = FieldAccessor_->GetValue(self);          value = (*DefaultCtor_)();      }  } @@ -1027,6 +1026,7 @@ TYsonStructParameter<TValue>& TYsonStructParameter<TValue>::Optional(bool init)      if (init) {          DefaultCtor_ = [] () { return TValue{}; }; +        DefaultIsDefaultConstruction_ = true;      }      return *this; diff --git a/yt/yt/core/ytree/yson_struct_detail.cpp b/yt/yt/core/ytree/yson_struct_detail.cpp index 8133575cd5a..14581c948df 100644 --- a/yt/yt/core/ytree/yson_struct_detail.cpp +++ b/yt/yt/core/ytree/yson_struct_detail.cpp @@ -27,14 +27,14 @@ bool ShouldThrow(EUnrecognizedStrategy strategy)  //////////////////////////////////////////////////////////////////////////////// -void TYsonStructMeta::SetDefaultsOfInitializedStruct(TYsonStructBase* target) const +void TYsonStructMeta::SetDefaultsOfInitializedStruct(TYsonStructBase* target, bool dontSetLiteMembers) const  {      if (auto* bitmap = target->GetSetFieldsBitmap()) {          bitmap->Initialize(ssize(Parameters_));      }      for (const auto& [_, parameter] : SortedParameters_) { -        parameter->SetDefaultsInitialized(target); +        parameter->SetDefaultsInitialized(target, dontSetLiteMembers);      }      for (const auto& preprocessor : Preprocessors_) { diff --git a/yt/yt/core/ytree/yson_struct_detail.h b/yt/yt/core/ytree/yson_struct_detail.h index b2a9c5ae14d..c074786dc2e 100644 --- a/yt/yt/core/ytree/yson_struct_detail.h +++ b/yt/yt/core/ytree/yson_struct_detail.h @@ -94,7 +94,7 @@ struct IYsonStructParameter      virtual void PostprocessParameter(const TYsonStructBase* self, const std::function<NYPath::TYPath()>& pathGetter) const = 0; -    virtual void SetDefaultsInitialized(TYsonStructBase* self) = 0; +    virtual void SetDefaultsInitialized(TYsonStructBase* self, bool dontSetLiteMembers = false) = 0;      virtual bool CanOmitValue(const TYsonStructBase* self) const = 0; @@ -121,7 +121,7 @@ struct IYsonStructMeta  {      virtual const THashMap<std::string, IYsonStructParameterPtr>& GetParameterMap() const = 0;      virtual const std::vector<std::pair<std::string, IYsonStructParameterPtr>>& GetParameterSortedList() const = 0; -    virtual void SetDefaultsOfInitializedStruct(TYsonStructBase* target) const = 0; +    virtual void SetDefaultsOfInitializedStruct(TYsonStructBase* target, bool dontSetLiteMembers = false) const = 0;      virtual const THashSet<std::string>& GetRegisteredKeys() const = 0;      virtual void PostprocessStruct(TYsonStructBase* target, const std::function<NYPath::TYPath()>& pathGetter) const = 0;      virtual IYsonStructParameterPtr GetParameter(const std::string& keyOrAlias) const = 0; @@ -163,7 +163,7 @@ class TYsonStructMeta      : public IYsonStructMeta  {  public: -    void SetDefaultsOfInitializedStruct(TYsonStructBase* target) const override; +    void SetDefaultsOfInitializedStruct(TYsonStructBase* target, bool dontSetLiteMembers = false) const override;      const THashMap<std::string, IYsonStructParameterPtr>& GetParameterMap() const override;      const std::vector<std::pair<std::string, IYsonStructParameterPtr>>& GetParameterSortedList() const override; @@ -295,7 +295,7 @@ public:          const std::function<void()>& validate) override;      void PostprocessParameter(const TYsonStructBase* self, const std::function<NYPath::TYPath()>& pathGetter) const override; -    void SetDefaultsInitialized(TYsonStructBase* self) override; +    void SetDefaultsInitialized(TYsonStructBase* self, bool dontSetLiteMembers = false) override;      void Save(const TYsonStructBase* self, NYson::IYsonConsumer* consumer) const override;      bool CanOmitValue(const TYsonStructBase* self) const override;      bool IsRequired() const override; @@ -357,6 +357,7 @@ private:      std::unique_ptr<IYsonFieldAccessor<TValue>> FieldAccessor_;      std::optional<std::function<TValue()>> DefaultCtor_; +    bool DefaultIsDefaultConstruction_ = false;      bool SerializeDefault_ = true;      std::vector<TValidator> Validators_;      std::vector<std::string> Aliases_; | 
