From 4eca2124896b93b8a542811edeb9d930bdae0668 Mon Sep 17 00:00:00 2001 From: Zufu Liu Date: Sun, 17 Nov 2024 10:08:59 +1100 Subject: Feature [feature-requests:#1533]. More performance for SCI_BRACEMATCH by avoiding costly NextPosition call where possible. Approximately 60% improvement on tested system. --- src/Document.cxx | 48 +++++++++++++++++++++++++++++++++++++++++------- src/Document.h | 1 + 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/Document.cxx b/src/Document.cxx index ef8bfce4d..0b34d5e73 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -1170,6 +1170,29 @@ bool Document::IsDBCSTrailByteNoExcept(char ch) const noexcept { return false; } +unsigned char Document::DBCSMinTrailByte() const noexcept { + switch (dbcsCodePage) { + case 932: + // Shift_jis + return 0x40; + case 936: + // GBK + return 0x40; + case 949: + // Korean Wansung KS C-5601-1987 + return 0x41; + case 950: + // Big5 + return 0x40; + case 1361: + // Korean Johab KS C-5601-1992 + return 0x31; + default: + // UTF-8 or single byte, should not occur as not DBCS + return 0; + } +} + int Document::DBCSDrawBytes(std::string_view text) const noexcept { if (text.length() <= 1) { return static_cast(text.length()); @@ -2828,8 +2851,8 @@ static char BraceOpposite(char ch) noexcept { // TODO: should be able to extend styled region to find matching brace Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxReStyle*/, Sci::Position startPos, bool useStartPos) noexcept { - const char chBrace = CharAt(position); - const char chSeek = BraceOpposite(chBrace); + const unsigned char chBrace = CharAt(position); + const unsigned char chSeek = BraceOpposite(chBrace); if (chSeek == '\0') return - 1; const int styBrace = StyleIndexAt(position); @@ -2838,8 +2861,15 @@ Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxRe direction = 1; int depth = 1; position = useStartPos ? startPos : NextPosition(position, direction); + + // Avoid complex NextPosition call for bytes that may not cause incorrect match + unsigned char maxSafeChar = 0xff; + if (dbcsCodePage != 0 && dbcsCodePage != CpUtf8) { + maxSafeChar = (direction >= 0) ? 0x80 : DBCSMinTrailByte() - 1; + } + while ((position >= 0) && (position < LengthNoExcept())) { - const char chAtPos = CharAt(position); + const unsigned char chAtPos = CharAt(position); if (chAtPos == chBrace || chAtPos == chSeek) { if ((position > GetEndStyled()) || (StyleIndexAt(position) == styBrace)) { depth += (chAtPos == chBrace) ? 1 : -1; @@ -2847,10 +2877,14 @@ Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxRe return position; } } - const Sci::Position positionBeforeMove = position; - position = NextPosition(position, direction); - if (position == positionBeforeMove) - break; + if (chAtPos <= maxSafeChar) { + position += direction; + } else { + const Sci::Position positionBeforeMove = position; + position = NextPosition(position, direction); + if (position == positionBeforeMove) + break; + } } return - 1; } diff --git a/src/Document.h b/src/Document.h index 01c608d0e..cecf02899 100644 --- a/src/Document.h +++ b/src/Document.h @@ -369,6 +369,7 @@ public: bool SCI_METHOD IsDBCSLeadByte(char ch) const override; bool IsDBCSLeadByteNoExcept(char ch) const noexcept; bool IsDBCSTrailByteNoExcept(char ch) const noexcept; + unsigned char DBCSMinTrailByte() const noexcept; int DBCSDrawBytes(std::string_view text) const noexcept; bool IsDBCSDualByteAt(Sci::Position pos) const noexcept; size_t SafeSegment(std::string_view text) const noexcept; -- cgit v1.2.3