aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Hal Canary <halcanary@google.com>2018-02-21 15:49:41 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-31 21:03:24 +0000
commitb4a8a629406fd84c04ecbb1bd2301cfbff91121d (patch)
tree23b8b2302de2243aeee5b6ae4fb084fb86accb2c
parent458f40a43e12260a3b73ee170b30d966d6c1fe56 (diff)
SkFloatToDecimal: optimize the less common cases.
bench PDFScalar_random goes from 120 ns to 70 ns. Change-Id: I6254f5c900395ee470ffee26303915025a8f0dda Reviewed-on: https://skia-review.googlesource.com/131151 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Ben Wagner <bungeman@google.com> Auto-Submit: Hal Canary <halcanary@google.com>
-rw-r--r--bench/PDFBench.cpp20
-rw-r--r--src/utils/SkFloatToDecimal.cpp24
2 files changed, 35 insertions, 9 deletions
diff --git a/bench/PDFBench.cpp b/bench/PDFBench.cpp
index bebf2b9f17..4cda80bd6e 100644
--- a/bench/PDFBench.cpp
+++ b/bench/PDFBench.cpp
@@ -40,21 +40,35 @@ DEF_BENCH(return new WStreamWriteTextBenchmark;)
// Test speed of SkFloatToDecimal for typical floats that
// might be found in a PDF document.
struct PDFScalarBench : public Benchmark {
+ PDFScalarBench(const char* n, float (*f)(SkRandom*)) : fName(n), fNextFloat(f) {}
+ const char* fName;
+ float (*fNextFloat)(SkRandom*);
bool isSuitableFor(Backend b) override {
return b == kNonRendering_Backend;
}
- const char* onGetName() override { return "PDFScalar"; }
+ const char* onGetName() override { return fName; }
void onDraw(int loops, SkCanvas*) override {
SkRandom random;
char dst[kMaximumSkFloatToDecimalLength];
while (loops-- > 0) {
- auto f = random.nextRangeF(-500.0f, 1500.0f);
+ auto f = fNextFloat(&random);
(void)SkFloatToDecimal(f, dst);
}
}
};
-DEF_BENCH(return new PDFScalarBench;)
+float next_common(SkRandom* random) {
+ return random->nextRangeF(-500.0f, 1500.0f);
+}
+float next_any(SkRandom* random) {
+ union { uint32_t u; float f; };
+ u = random->nextU();
+ static_assert(sizeof(float) == sizeof(uint32_t), "");
+ return f;
+}
+
+DEF_BENCH(return new PDFScalarBench("PDFScalar_common", next_common);)
+DEF_BENCH(return new PDFScalarBench("PDFScalar_random", next_any);)
#ifdef SK_SUPPORT_PDF
diff --git a/src/utils/SkFloatToDecimal.cpp b/src/utils/SkFloatToDecimal.cpp
index 273175a897..f2a155398b 100644
--- a/src/utils/SkFloatToDecimal.cpp
+++ b/src/utils/SkFloatToDecimal.cpp
@@ -13,6 +13,22 @@
#include "SkTypes.h"
+// returns `value * pow(base, e)`, assuming `e` is positive.
+static double pow_by_squaring(double value, double base, int e) {
+ // https://en.wikipedia.org/wiki/Exponentiation_by_squaring
+ SkASSERT(e > 0);
+ while (true) {
+ if (e & 1) {
+ value *= base;
+ }
+ e >>= 1;
+ if (0 == e) {
+ return value;
+ }
+ base *= base;
+ }
+}
+
// Return pow(10.0, e), optimized for common cases.
static double pow10(int e) {
switch (e) {
@@ -34,14 +50,10 @@ static double pow10(int e) {
case 15: return 1e+15;
default:
if (e > 15) {
- double value = 1e+15;
- while (e-- > 15) { value *= 10.0; }
- return value;
+ return pow_by_squaring(1e+15, 10.0, e - 15);
} else {
SkASSERT(e < 0);
- double value = 1.0;
- while (e++ < 0) { value /= 10.0; }
- return value;
+ return pow_by_squaring(1.0, 0.1, -e);
}
}
}