From 151b0a7766a115103416e48a6c9e0bf5acc2a5aa Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 6 Mar 2024 12:49:31 +0100 Subject: Add WriteMeasuredVarUInt to avoid measuring ints twice before writing (#665) Avoid double resize of buffer in CbWriter::SetName and CbWriter::AddBinary Add WriteMeasuredVarUInt to avoid measuring ints twice before writing --- src/zencore/compactbinarybuilder.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'src/zencore/compactbinarybuilder.cpp') diff --git a/src/zencore/compactbinarybuilder.cpp b/src/zencore/compactbinarybuilder.cpp index 5c08d2e6e..3331291ce 100644 --- a/src/zencore/compactbinarybuilder.cpp +++ b/src/zencore/compactbinarybuilder.cpp @@ -221,12 +221,11 @@ CbWriter::SetName(const std::string_view Name) State.Flags |= StateFlags::Name; const uint32_t NameLenByteCount = MeasureVarUInt(uint32_t(Name.size())); const int64_t NameLenOffset = Data.size(); - Data.resize(NameLenOffset + NameLenByteCount); + Data.resize(NameLenOffset + NameLenByteCount + Name.size()); - WriteVarUInt(uint64_t(Name.size()), Data.data() + NameLenOffset); + WriteMeasuredVarUInt(uint64_t(Name.size()), NameLenByteCount, Data.data() + NameLenOffset); - const uint8_t* NamePtr = reinterpret_cast(Name.data()); - Data.insert(Data.end(), NamePtr, NamePtr + Name.size()); + memcpy(Data.data() + NameLenOffset + NameLenByteCount, Name.data(), Name.size()); return *this; } @@ -341,7 +340,7 @@ CbWriter::EndObject() const uint64_t Size = uint64_t(Data.size() - PayloadOffset); const uint32_t SizeByteCount = MeasureVarUInt(Size); Data.insert(Data.begin() + PayloadOffset, SizeByteCount, 0); - WriteVarUInt(Size, Data.data() + PayloadOffset); + WriteMeasuredVarUInt(Size, SizeByteCount, Data.data() + PayloadOffset); EndField(bUniform ? CbFieldType::UniformObject : CbFieldType::Object); } @@ -400,8 +399,8 @@ CbWriter::EndArray() const uint64_t Size = uint64_t(Data.size() - PayloadOffset) + CountByteCount; const uint32_t SizeByteCount = MeasureVarUInt(Size); Data.insert(Data.begin() + PayloadOffset, SizeByteCount + CountByteCount, 0); - WriteVarUInt(Size, Data.data() + PayloadOffset); - WriteVarUInt(Count, Data.data() + PayloadOffset + SizeByteCount); + WriteMeasuredVarUInt(Size, SizeByteCount, Data.data() + PayloadOffset); + WriteMeasuredVarUInt(Count, CountByteCount, Data.data() + PayloadOffset + SizeByteCount); EndField(bUniform ? CbFieldType::UniformArray : CbFieldType::Array); } @@ -429,13 +428,13 @@ CbWriter::AddNull() void CbWriter::AddBinary(const void* const Value, const uint64_t Size) { - const size_t SizeByteCount = MeasureVarUInt(Size); + const uint32_t SizeByteCount = MeasureVarUInt(Size); Data.reserve(Data.size() + 1 + SizeByteCount + Size); BeginField(); const size_t SizeOffset = Data.size(); - Data.resize(Data.size() + SizeByteCount); - WriteVarUInt(Size, Data.data() + SizeOffset); - Data.insert(Data.end(), static_cast(Value), static_cast(Value) + Size); + Data.resize(Data.size() + SizeByteCount + Size); + WriteMeasuredVarUInt(Size, SizeByteCount, Data.data() + SizeOffset); + memcpy(Data.data() + SizeOffset + SizeByteCount, Value, Size); EndField(CbFieldType::Binary); } @@ -468,7 +467,7 @@ CbWriter::AddString(const std::string_view Value) Data.resize(Offset + SizeByteCount + Size); uint8_t* StringData = Data.data() + Offset; - WriteVarUInt(Size, StringData); + WriteMeasuredVarUInt(Size, SizeByteCount, StringData); StringData += SizeByteCount; if (Size > 0) { @@ -489,7 +488,7 @@ CbWriter::AddString(const std::wstring_view Value) const int64_t Offset = Data.size(); Data.resize(Offset + SizeByteCount + Size); uint8_t* StringData = Data.data() + Offset; - WriteVarUInt(Size, StringData); + WriteMeasuredVarUInt(Size, SizeByteCount, StringData); StringData += SizeByteCount; if (Size > 0) { @@ -511,7 +510,7 @@ CbWriter::AddInteger(const int32_t Value) const uint32_t MagnitudeByteCount = MeasureVarUInt(Magnitude); const int64_t Offset = Data.size(); Data.resize(Offset + MagnitudeByteCount); - WriteVarUInt(Magnitude, Data.data() + Offset); + WriteMeasuredVarUInt(Magnitude, MagnitudeByteCount, Data.data() + Offset); EndField(CbFieldType::IntegerNegative); } @@ -526,7 +525,7 @@ CbWriter::AddInteger(const int64_t Value) const uint64_t Magnitude = ~uint64_t(Value); const uint32_t MagnitudeByteCount = MeasureVarUInt(Magnitude); const uint64_t Offset = AddUninitialized(Data, MagnitudeByteCount); - WriteVarUInt(Magnitude, Data.data() + Offset); + WriteMeasuredVarUInt(Magnitude, MagnitudeByteCount, Data.data() + Offset); EndField(CbFieldType::IntegerNegative); } @@ -537,7 +536,7 @@ CbWriter::AddInteger(const uint32_t Value) BeginField(); const uint32_t ValueByteCount = MeasureVarUInt(Value); const uint64_t Offset = AddUninitialized(Data, ValueByteCount); - WriteVarUInt(Value, Data.data() + Offset); + WriteMeasuredVarUInt(Value, ValueByteCount, Data.data() + Offset); EndField(CbFieldType::IntegerPositive); } @@ -548,7 +547,7 @@ CbWriter::AddInteger(const uint64_t Value) BeginField(); const uint32_t ValueByteCount = MeasureVarUInt(Value); const uint64_t Offset = AddUninitialized(Data, ValueByteCount); - WriteVarUInt(Value, Data.data() + Offset); + WriteMeasuredVarUInt(Value, ValueByteCount, Data.data() + Offset); EndField(CbFieldType::IntegerPositive); } -- cgit v1.2.3 From 9b2fb8069869ec5cea32816a3589d9842595ffea Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Mon, 2 Dec 2024 14:26:11 +0100 Subject: reduce memory churn (#248) * eliminated allocation in SetCurrentThreadName * reduced memory allocator activity in cache RPC response building * reduced allocations in compact binary building --- src/zencore/compactbinarybuilder.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/zencore/compactbinarybuilder.cpp') diff --git a/src/zencore/compactbinarybuilder.cpp b/src/zencore/compactbinarybuilder.cpp index 3331291ce..a60de023d 100644 --- a/src/zencore/compactbinarybuilder.cpp +++ b/src/zencore/compactbinarybuilder.cpp @@ -93,6 +93,7 @@ AppendCompactBinary(const CbFieldView& Value, std::vector& OutData) CbWriter::CbWriter() { + States.reserve(4); States.emplace_back(); } -- cgit v1.2.3 From 920120bbcec9f91df3336f62970b3e010a4fa6c2 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Thu, 6 Mar 2025 16:18:32 +0100 Subject: reduced memory churn using fixed_xxx containers (#236) * Added EASTL to help with eliminating memory allocations * Applied EASTL to eliminate memory allocations, primarily by using `fixed_vector` et al to use stack allocations / inline struct allocations Reduces memory events in traces by close to a factor of 10 in test scenario (starting editor for project F) --- src/zencore/compactbinarybuilder.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/zencore/compactbinarybuilder.cpp') diff --git a/src/zencore/compactbinarybuilder.cpp b/src/zencore/compactbinarybuilder.cpp index a60de023d..63c0b9c5c 100644 --- a/src/zencore/compactbinarybuilder.cpp +++ b/src/zencore/compactbinarybuilder.cpp @@ -15,23 +15,21 @@ namespace zen { -template uint64_t -AddUninitialized(std::vector& Vector, uint64_t Count) +AddUninitialized(CbWriter::CbWriterData_t& Vector, uint64_t Count) { const uint64_t Offset = Vector.size(); Vector.resize(Offset + Count); return Offset; } -template uint64_t -Append(std::vector& Vector, const T* Data, uint64_t Count) +Append(CbWriter::CbWriterData_t& Vector, const uint8_t* Data, uint64_t Count) { const uint64_t Offset = Vector.size(); Vector.resize(Offset + Count); - memcpy(Vector.data() + Offset, Data, sizeof(T) * Count); + memcpy(Vector.data() + Offset, Data, sizeof(uint8_t) * Count); return Offset; } @@ -76,7 +74,7 @@ IsUniformType(const CbFieldType Type) /** Append the payload from the compact binary value to the array and return its type. */ static inline CbFieldType -AppendCompactBinary(const CbFieldView& Value, std::vector& OutData) +AppendCompactBinary(const CbFieldView& Value, CbWriter::CbWriterData_t& OutData) { struct FCopy : public CbFieldView { @@ -93,7 +91,6 @@ AppendCompactBinary(const CbFieldView& Value, std::vector& OutData) CbWriter::CbWriter() { - States.reserve(4); States.emplace_back(); } -- cgit v1.2.3