[postgis-tickets] [PostGIS] #4543: Use Ryū to output floating point numbers

PostGIS trac at osgeo.org
Mon Oct 14 09:12:54 PDT 2019


#4543: Use Ryū to output floating point numbers
-------------------------+---------------------------
 Reporter:  Algunenano   |      Owner:  Algunenano
     Type:  enhancement  |     Status:  assigned
 Priority:  medium       |  Milestone:  PostGIS 3.1.0
Component:  liblwgeom    |    Version:  trunk
 Keywords:               |
-------------------------+---------------------------
 PG12 introduced an implementation of Ryū
 (https://dl.acm.org/citation.cfm?id=3192369) to speed up the
 transformation between floating points and strings, as it can be 10x
 faster than a straight `sprintf(str, "%f", double)`.

 It seemed to me that multiple Postgis' functions could use a similar
 improvement so I've tested nasty hack to use Postgres' RYU implementation
 for `lwprint_double` (this is a hack, so it doesn't take into account
 desired precision or space left in the buffer):

 Before:
 {{{
 explain analyze Select ST_AsText(the_geom) from
 benchmark_4c7214d90a79aa6760367a084a4d4a2f61fbe1c6cc4f7f9e76020;
 QUERY PLAN
 ------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Seq Scan on
 benchmark_4c7214d90a79aa6760367a084a4d4a2f61fbe1c6cc4f7f9e76020
 (cost=0.00..33.63 rows=13 width=32) (actual time=547.194..5313.276 rows=13
 loops=1)
  Planning Time: 0.144 ms
  Execution Time: 5313.322 ms
 (3 rows)
 }}}

 After:
 {{{
  Seq Scan on
 benchmark_4c7214d90a79aa6760367a084a4d4a2f61fbe1c6cc4f7f9e76020
 (cost=0.00..33.63 rows=13 width=32) (actual time=64.062..478.339 rows=13
 loops=1)
  Planning Time: 0.628 ms
  Execution Time: 478.373 ms
 (3 rows)
 }}}


 The hack involves using PG function in liblwgeom, so that's a no-go from
 the start, but it's useful to compare performance and see what kind of
 improvement we could expect to get if we decided to go that way:

 {{{
 diff --git a/liblwgeom/lwprint.c b/liblwgeom/lwprint.c
 index af56c4c27..1a0dc886d 100644
 --- a/liblwgeom/lwprint.c
 +++ b/liblwgeom/lwprint.c
 @@ -486,27 +486,13 @@ trim_trailing_zeros(char* str)
   * truncated and misses a terminating NULL.
   *
   */
 +/* This is also provided by snprintf.c */
 +extern int double_to_shortest_decimal_bufn(double f, char *result);
 +
  int
  lwprint_double(double d, int maxdd, char* buf, size_t bufsize)
  {
 -  double ad = fabs(d);
 -  int ndd;
 -  int length = 0;
 -  if (ad <= FP_TOLERANCE)
 -  {
 -      d = 0;
 -      ad = 0;
 -  }
 -  if (ad < OUT_MAX_DOUBLE)
 -  {
 -      ndd = ad < 1 ? 0 : floor(log10(ad)) + 1; /* non-decimal digits */
 -      if (maxdd > (OUT_MAX_DOUBLE_PRECISION - ndd)) maxdd -= ndd;
 -      length = snprintf(buf, bufsize, "%.*f", maxdd, d);
 -  }
 -  else
 -  {
 -      length = snprintf(buf, bufsize, "%g", d);
 -  }
 -  trim_trailing_zeros(buf);
 -  return length;
 +    int b = double_to_shortest_decimal_bufn(d, buf);
 +    buf[b] = 0;
 +    return b;
  }
 \ No newline at end of file
 }}}

-- 
Ticket URL: <https://trac.osgeo.org/postgis/ticket/4543>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.


More information about the postgis-tickets mailing list