[geos-devel] Upgrading to geos 3.3.0 broke all our codebase !
Maxime van Noppen
maxime at altribe.org
Fri Jul 8 07:23:05 EDT 2011
On 07/08/2011 12:31 PM, Sandro Santilli wrote:
> The rationale was: follow JTS.
Which is a very good one indeed, though how does JTS handle the diamond
inheritance? I thought Java didn't permit it (though I really never done
much Java).
> If you read the mailing lists you should be aware that using
> the C++ API is not recommended.
> Clients of the C-API are stable since GEOS-2.2.0
Yes but it's so much better from a C++ point-of-view it's hard to go
back to old C-style code.
> Note that using static_cast is generally a bad habit and
> should be avoided.
What?! Do you really understand what static_cast is? static_cast should
always be preferred over dynamic_cast when applicable, precisely for
performance (static_cast is computed at compilation as opposed to
dynamic_cast which requires dynamic lookup).
Moreover sometimes you just can't use dynamic_cast and must use
static_cast. For example you can't downcast a non-polymorphic class
using dynamic_ast... static_cast is mandatory here.
It's like saying that the operator[] of std::vector is bad and
std::vector::at should be preferred because it always performs a
boundary check. If you want to be safe, sure, go for std::vector::at but
when you explicitly know your index is good, there's no reason to prefer
it over operator[].
This is an example of code which was broken:
void point::reset(const geos::geom::Point* geom)
{
if (geom == 0)
geom_.reset();
else
geom_.reset(static_cast<geos::geom::Point*>(geom->clone()));
}
We have a point class which wraps a geos::geom::Point to add some of our
specific code. In this case, it was perfectly valid (and recommended) to
use a static_cast.
> Profiling informations comparing GEOS-3.2 and GEOS-3.3 are welcome.
We care a lot about performance. In specific intensive loops this might
add 0.1 to 3% (wild guess based on previous profiling of the code) of
overhead. I don't think I'll have the time to set up a proper benchmark
though. Anyways this would be a bit pointless because I'm not asking at
all for a change in geos code as following JTS seems to be the right
thing. I'll probably have to rethink some parts of our code though to
avoid casts, but that's another story. :)
A very-very-simple-and-naive test to have some feedback:
---------------------------------------------------------------
#include <iostream>
#include <list>
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/Point.h>
int main()
{
geos::geom::GeometryFactory gf;
std::list<geos::geom::Point*> point_list;
geos::geom::Coordinate c;
c.x = 0;
c.y = 0;
geos::geom::Geometry* p = gf.createPoint(c);
for (unsigned int i = 0; i < 100000; ++i)
point_list.push_back(dynamic_cast<geos::geom::Point*>(p));
std::cout << point_list.size() << std::endl;
}
---------------------------------------------------------------
Compiled with g++ -03, this yields these results:
- main() : 100%
- dynamic_cast : 41%
- operator new : 31.6%
- operator delete : 15.2%
This enlightens the cost of dynamic_cast which can really be a big hit
on such specific and intensive loops.
Thanks for the answer.
--
Maxime
More information about the geos-devel
mailing list