2

I need to create an 3D R*-tree, perhaps for long time storage, but performance will also be an issue. In order to create the tree, I decided to use Boost's spacialindex and basically found two possible methods.

Either I create it directly using objects as it's here: Index of polygons stored in vector, however that does not allow me to store and load it without creating the R*-tree again.

Or I could use a mapped file as explained here: Index stored in mapped file using Boost.Interprocess, however, I am not sure if the performance of queries is good enough in this case.

My r-tree will contain several thousand entries, but most likely less than about 100,000. Now my question is, is there any strong performance issue by using mapped files compared to using the standard objects? Also, if the creation of an R*-tree of about 100,000 values does not take a substanial amount of time (I could have all bounding boxes and corresponding keys/data stored in a file) then it might be a better option to skip the mapped file and just create the tree every time I run the program?

Hopefully, somebody can help me here, as the documentation does not really provide much information (though it's still worlds better than the documentation of libspacialindex).

philkark
  • 2,417
  • 7
  • 38
  • 59

2 Answers2

4

A mapped file will behave mostly like regular memory (in fact, in Linux, memory allocation with new or malloc will use mmap [with a "no file" backing storage] as the underlying allocation method). However, if you do many small writes "all over the place", and you are mapping over a REAL FILE, then the OS will restrict the amount of buffered writes before writing to the file.

I did some experiments when the subject came up a while ago, and by adjusting the settings for how the OS deals with these "pending writes", I got reasonably performance even for filebacked memory mapping with random read/write pattern [something I expect happens when you are building your tree].

Here's the "performance of mmap with random writes" question, which I think is highly related: Bad Linux Memory Mapped File Performance with Random Access C++ & Python (This answer applies to Linux - other OS's, in particular Windows, may well behave completely differently with regards to how it deals with writes to mapped files)

Of course, it's pretty hard to say "which is better", between memory mapped file or rebuild every time the program is run - it really depends on what your application does, whether you run it 100 times a second, or once a day, how long it takes to rebuild [I have absolutely no idea!], and lots of other such things. There are two choices: Build the simplest version, and see if it's "fast enough", or build both versions, and measure how much difference there is, and then decide which path to go down.

I tend to build the simple(ish) model, and if performance isn't good enough, figure out where the slowness comes from, and then fix that - it saves spending lots of time making something that takes 0.01% of the total execution time run 5 clock-cycles faster, and ending up with a big thinko somewhere else that makes it run 500 times slower than you expected...

Community
  • 1
  • 1
Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Thanks for your quick answer. You are right of course that it totally depends on the use of the program, unfortunately, if you work in a larger project and it's not conclusive yet how my part will be used exactly and I will probably not know before I have to be done. Thank you for pointing out your performance test, I will have a look at it. If noone (e.g. Adam Wulkiewicz, who created this library) answers, I will accept yours. It might not be an exact answer to my question, but covers the topic in general. – philkark Jan 30 '15 at 09:02
  • This answer is not bad but is way too specific, as the OP does not indicate his operating system and all of the real content only applies to Linux. – Puppy Jan 30 '15 at 09:07
  • I have added my operating system to the tags! Thanks for pointing it out. – philkark Jan 30 '15 at 09:09
  • @Puppy: Pointed out that this performance analysis is "only linux", but I'm not aware of any other reason than "flushing writes" being the reason for slowness - of course, Windows may not have an adjustment on that.... Or do you actually know of a reason why "mapped files don't behave like regular memory" in some other OS? – Mats Petersson Jan 30 '15 at 09:11
  • Also, if you are building a module that is to be integrated into another, larger program, it would be prudent to try to find out whether performance of your module is "super critical, because it's being used every time you do X, and X is very common in our system", or "not so critical, because it only happens about once a day, and latency in this situation isn't too critical" [note that "happen rarely" does not really mean "not performance critical" - in an automotive system, the anti-lock brakes are expected to work "quickly", even if it's not often, where starting the engine "doesn't matter" – Mats Petersson Jan 30 '15 at 09:14
0

Bulk-loading the index is much faster than repeated insertion, and yields a much more efficient tree. So if you can hold all your data in main memory, I suggest rebuilding the tree using STR bulk loading. In my experience this is more than fast enough (bulk loading time is dwarfed by I/O time).

Cost of STR is roughly that of sorting. O(n log n) theoretically, with very low constants (a less efficient implementation may be O(n log n log n) but that still is fairly cheap).

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
  • Thank you for your reply. I initially wanted to implement the packing algorithm, but couldn't find how to create the tree. Along with bgi::rstar, bgi::linear, and bgi::quadratic I did not find anything else (bgi = boost::geometry::index). Also, how exactly could that solve my problem with storage etc.? – philkark Jan 30 '15 at 09:07
  • I haven't used bgi, so I don't know if that functionality is available. But it's easier to implement than the full R* tree, so I would be surprised if they don't have bulk loads. Bulk-loading is cheap, I don't think you need to store the tree then. – Has QUIT--Anony-Mousse Jan 30 '15 at 09:27
  • Thanks, I will look into that and see, if I can find still find it. Yes, if the tree is created quickly anyway, then I will not need to store it and just create it every time, that way it might also be easier to update the data, by just adding additional bounding boxes with keys to the file. – philkark Jan 30 '15 at 09:34