diff --git a/easy_profiler_core/outstream.h b/easy_profiler_core/outstream.h index 6ffc8e7..a1272cd 100644 --- a/easy_profiler_core/outstream.h +++ b/easy_profiler_core/outstream.h @@ -60,6 +60,11 @@ namespace profiler { m_stream.write((const char*)&_data, sizeof(T)); } + ::std::stringstream& stream() + { + return m_stream; + } + const ::std::stringstream& stream() const { return m_stream; diff --git a/easy_profiler_core/profile_manager.cpp b/easy_profiler_core/profile_manager.cpp index c80d304..d965eda 100644 --- a/easy_profiler_core/profile_manager.cpp +++ b/easy_profiler_core/profile_manager.cpp @@ -1009,11 +1009,22 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream, bo uint32_t ProfileManager::dumpBlocksToFile(const char* _filename) { + std::ofstream outputFile(_filename, std::fstream::binary); + if (!outputFile.is_open()) + return 0; + profiler::OStream outputStream; + + // Replace outputStream buffer to outputFile buffer to avoid redundant copying + typedef ::std::basic_iostream stringstream_parent; + stringstream_parent& s = outputStream.stream(); + auto oldbuf = s.rdbuf(outputFile.rdbuf()); + + // Write data directly to file const auto blocksNumber = dumpBlocksToStream(outputStream, true); - std::ofstream of(_filename, std::fstream::binary); - of << outputStream.stream().str(); + // Restore old outputStream buffer to avoid possible second memory free on stringstream destructor + s.rdbuf(oldbuf); return blocksNumber; } diff --git a/easy_profiler_core/reader.cpp b/easy_profiler_core/reader.cpp index fbd1aa9..5da363c 100644 --- a/easy_profiler_core/reader.cpp +++ b/easy_profiler_core/reader.cpp @@ -372,12 +372,16 @@ extern "C" { ::std::stringstream str; + // Replace str buffer to inFile buffer to avoid redundant copying typedef ::std::basic_iostream<::std::stringstream::char_type, ::std::stringstream::traits_type> stringstream_parent; stringstream_parent& s = str; auto oldbuf = s.rdbuf(inFile.rdbuf()); + // Read data from file auto result = fillTreesFromStream(progress, str, serialized_blocks, serialized_descriptors, descriptors, blocks, threaded_trees, total_descriptors_number, gather_statistics, _log); + + // Restore old str buffer to avoid possible second memory free on stringstream destructor s.rdbuf(oldbuf); return result;