]> granicus.if.org Git - graphviz/commitdiff
optimize two calls to gvprintf with single characters
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Fri, 21 May 2021 02:34:36 +0000 (19:34 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Thu, 27 May 2021 04:26:38 +0000 (21:26 -0700)
The expression `gvprintf(j, "%c", x)` is equivalent to `gvwrite(j, &x, 1)`.
However, it seems modern compilers, even with link-time optimization enabled,
are not clever enough to see this equivalence. By unraveling the gvprintf call
to what it eventually bottoms out to, we can accelerate SVG generation.

On tests/regression_tests/large/long_chain, this drops the number of gvprintf
calls from 297008 to 165008, reducing the amount of the trace for which gvprintf
is responsible from 3.27% to 2.24%. Total executed instructions are reduced from
8160974807 to 8098098396, a speed up of ~1%.

plugin/core/gvrender_core_svg.c

index 8a6c4989b3f2e6ae62eee6e591811b193211845d..a852b4db1c9f379de584a5cae2f52019c324e5dc 100644 (file)
@@ -59,7 +59,7 @@ static void svg_bzptarray(GVJ_t * job, pointf * A, int n)
     if (A[0].x <= A[n-1].x) {
 #endif
        for (i = 0; i < n; i++) {
-           gvprintf(job, "%c", c);
+           gvwrite(job, &c, 1);
             gvprintdouble(job, A[i].x);
             gvputs(job, ",");
             gvprintdouble(job, -A[i].y);
@@ -71,7 +71,7 @@ static void svg_bzptarray(GVJ_t * job, pointf * A, int n)
 #if EDGEALIGN
     } else {
        for (i = n-1; i >= 0; i--) {
-           gvprintf(job, "%c", c);
+           gvwrite(job, &c, 1);
             gvprintdouble(job, A[i].x);
             gvputs(job, ",");
             gvprintdouble(job, -A[i].y);