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:
                /**

Reply via email to