This is an automated email from the ASF dual-hosted git repository. swebb2066 pushed a commit to branch avoid_noop_encoding in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
commit 214618948d82ff3bcc6f73b87a77d0a4b5a7c28c Author: Stephen Webb <[email protected]> AuthorDate: Wed Aug 9 16:10:42 2023 +1000 Reduce logging overhead when the output is unchanged by the character encoding --- src/main/cpp/charsetencoder.cpp | 15 ++++++++++++ src/main/cpp/outputstreamwriter.cpp | 30 ++++++++++++++--------- src/main/include/log4cxx/helpers/charsetencoder.h | 6 +++++ 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/main/cpp/charsetencoder.cpp b/src/main/cpp/charsetencoder.cpp index df61e487..5f08b103 100644 --- a/src/main/cpp/charsetencoder.cpp +++ b/src/main/cpp/charsetencoder.cpp @@ -644,3 +644,18 @@ void CharsetEncoder::encode(CharsetEncoderPtr& enc, dst.put(Transcoder::LOSSCHAR); } } + +bool CharsetEncoder::isTriviallyCopyable(const LogString& src, CharsetEncoderPtr& enc) +{ + bool result = false; + if (dynamic_cast<LocaleCharsetEncoder*>(enc.get())) + { + result = src.end() == std::find_if(src.begin(), src.end() + , [](const logchar& ch) -> bool { return 0x80 <= (unsigned int)ch; }); + } +#if LOG4CXX_LOGCHAR_IS_UTF8 + else + result = !!dynamic_cast<TrivialCharsetEncoder*>(enc.get()); +#endif + return result; +} diff --git a/src/main/cpp/outputstreamwriter.cpp b/src/main/cpp/outputstreamwriter.cpp index 4ddf93c9..1ebd320e 100644 --- a/src/main/cpp/outputstreamwriter.cpp +++ b/src/main/cpp/outputstreamwriter.cpp @@ -78,18 +78,29 @@ void OutputStreamWriter::flush(Pool& p) void OutputStreamWriter::write(const LogString& str, Pool& p) { - if (str.length() > 0) + if (str.empty()) + return; + if (CharsetEncoder::isTriviallyCopyable(str, m_priv->enc)) { + ByteBuffer buf((char*)str.data(), str.size() * sizeof (logchar)); + m_priv->out->write(buf, p); + } + else + { + enum { BUFSIZE = 1024 }; + char stackData[BUFSIZE]; + char* rawbuf = stackData; + size_t bufSize = BUFSIZE; #ifdef LOG4CXX_MULTI_PROCESS + std::vector<char> heapData; // Ensure the logging event is a single write system call to keep events from each process separate - size_t bufSize = str.length() * 2; - char* rawbuf = new char[bufSize]; - ByteBuffer buf(rawbuf, (size_t) bufSize); -#else - enum { BUFSIZE = 1024 }; - char rawbuf[BUFSIZE]; - ByteBuffer buf(rawbuf, (size_t) BUFSIZE); + if (bufSize < str.length() * 2) + { + heapData.resize(bufSize = str.length() * 2) + rawbuf = heapData.data(); + } #endif + ByteBuffer buf(rawbuf, bufSize); m_priv->enc->reset(); LogString::const_iterator iter = str.begin(); @@ -105,9 +116,6 @@ void OutputStreamWriter::write(const LogString& str, Pool& p) m_priv->enc->flush(buf); buf.flip(); m_priv->out->write(buf, p); -#ifdef LOG4CXX_MULTI_PROCESS - delete []rawbuf; -#endif } } diff --git a/src/main/include/log4cxx/helpers/charsetencoder.h b/src/main/include/log4cxx/helpers/charsetencoder.h index c54e35dd..f85d8451 100644 --- a/src/main/include/log4cxx/helpers/charsetencoder.h +++ b/src/main/include/log4cxx/helpers/charsetencoder.h @@ -116,6 +116,12 @@ class LOG4CXX_EXPORT CharsetEncoder : public Object return (stat != 0); } + /** + * Is the data of \c src unchanged by \c enc. + * + */ + static bool isTriviallyCopyable(const LogString& src, CharsetEncoderPtr& enc); + private: /**
