From 89030379ea1c2621fca24d91eaff92aea44686da Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Mon, 31 Aug 2009 16:14:45 +0200 Subject: Speed-up floating-point decoding for SVG parsing. Instead of comparing the character to '0' and '9', use bit fiddling to detect that the character is a digit between '0' and '9'. Loading tiger.svg (tests/benchmarks/qsvgrenderer) is now 10% faster, going down from 85.3 millions instructions to 77.2 millions. Mostly this is due 46% speed-up in parseNumbersList() function, from 26.9 millions instructions to just 18.4 millions. Reviewed-by: Kim --- src/svg/qsvghandler.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 8a68cc3..6ff885a 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -474,6 +474,13 @@ public: } }; +// '0' is 0x30 and '9' is 0x39 +static inline bool isDigit(ushort ch) +{ + static quint16 magic = 0x3ff; + return ((ch >> 4) == 3) && (magic >> (ch & 15)); +} + static qreal toDouble(const QChar *&str) { const int maxLen = 255;//technically doubles can go til 308+ but whatever @@ -486,7 +493,7 @@ static qreal toDouble(const QChar *&str) } else if (*str == QLatin1Char('+')) { ++str; } - while (*str >= QLatin1Char('0') && *str <= QLatin1Char('9') && pos < maxLen) { + while (isDigit(str->unicode()) && pos < maxLen) { temp[pos++] = str->toLatin1(); ++str; } @@ -494,7 +501,7 @@ static qreal toDouble(const QChar *&str) temp[pos++] = '.'; ++str; } - while (*str >= QLatin1Char('0') && *str <= QLatin1Char('9') && pos < maxLen) { + while (isDigit(str->unicode()) && pos < maxLen) { temp[pos++] = str->toLatin1(); ++str; } @@ -507,7 +514,7 @@ static qreal toDouble(const QChar *&str) temp[pos++] = str->toLatin1(); ++str; } - while (*str >= QLatin1Char('0') && *str <= QLatin1Char('9') && pos < maxLen) { + while (isDigit(str->unicode()) && pos < maxLen) { temp[pos++] = str->toLatin1(); ++str; } @@ -587,7 +594,7 @@ static QVector parseNumbersList(const QChar *&str) while (*str == QLatin1Char(' ')) ++str; - while ((*str >= QLatin1Char('0') && *str <= QLatin1Char('9')) || + while (isDigit(str->unicode()) || *str == QLatin1Char('-') || *str == QLatin1Char('+') || *str == QLatin1Char('.')) { -- cgit v0.12