logo separator

[mkgmap-dev] performance best practice

From Joris Bo jorisbo at hotmail.com on Sat May 30 12:01:31 BST 2020

Thx for the answer !

-----Oorspronkelijk bericht-----
Van: mkgmap-dev <mkgmap-dev-bounces at lists.mkgmap.org.uk> Namens Gerd Petermann
Verzonden: zaterdag 30 mei 2020 11:18
Aan: Development list for mkgmap <mkgmap-dev at lists.mkgmap.org.uk>
Onderwerp: Re: [mkgmap-dev] performance best practice

Hi Joris,

yes, the evaluation of rules is already highly optimized.
1) It uses an index to filter those rules which cannot match.
So, for a way which doesn't have a building tag a rule like
building=* & is_in(...) ....
is simply ignored unless there is a rule which might set the building tag.
2) It uses caches to remember the results of repeated evaluations. Assume that you have highway=residential & surface=paved & (smoothness=bad | smoothness =horrible) [...] highway=residential & surface=paved & (smoothness=intermediate) [...] highway=residential & surface=paved [...] With a highway that has the tags highway=residential  and surface=paved  but no smoothness tag the first two rules will not match but they are probably evaluated. Since the 2nd and 3rd rule contain the same expression highway=residential & surface=paved mkgmap remembers this result as long as no tags are changed.
2a) A BAD idea regarding performance would be this:
highway=residential & surface=paved {set paved_residential=true} paved_residential=true &  (smoothness=bad | smoothness =horrible) [...] paved_residential=true & (smoothness=intermediate) [...] paved_residential=true [...] as this requires more memory and more evaluations. It might make the rules easier to understand though.

2b) Up to now using if () doesn't improve performance. It is just a means to improve readability and the better alternative to the above BAD approach.
So, using
if (highway=residential & surface=paved) then
  (smoothness=bad | smoothness =horrible) [...]
  (smoothness=intermediate) [...]
can be easier to understand, but currently mkgmap translates it back to the longer rules shown in 2) and thus performance should be equal.

In general, the evaluation of tags is very fast compared with the evaluation of e.g. a is_in(...) style function.


Von: mkgmap-dev <mkgmap-dev-bounces at lists.mkgmap.org.uk> im Auftrag von Joris Bo <jorisbo at hotmail.com>
Gesendet: Samstag, 30. Mai 2020 10:35
An: Development list for mkgmap
Betreff: [mkgmap-dev] performance best practice


I have a question about improving performance (I'm very happy already, I think is absolutely fast enough, its just that I could improve by doing things differently)

I assume the is_in() function requires extra calculations and lookups which may cost time as well calculating unnecessary rules (That could already be a wrong assumption)

Maybe an expert could just say what would be better in general. No need to prove or test. I tried myself some things which actually did not make a big difference.
For example I moved the rules for buildings to the top of the style and expected serious improvements, because buildings are the majority of polygons in the PBF But I gained only a little bit (3-5%? max) and even one out of 4 runs it was even a bit slower. So mkgmap must be very optimized already was my conclusion

Question 1)      'unnecessary' processing rules

                        Answer A
Walk through 100 rules about highways when it's a waterway or railway and just wait for rule 101

                        Answer B
                                   Introduce an extra IF, which causes extra calculation itself but skips the 100 rules IF (highway = *) Then
                                                Highway 1,2,3,4,5,6,7,8-100 END
                                    Waterway = river [0x18 resolution 22]

Question 2)      Help mkgmap to avoid calculation of possible expensive calculations? Or is it already smart enough to not start the IS_IN() if "name = *" failed already

                        Answer A
                                   waterway = river & name = * & is_in(natural, sea, any) = true    [0x18 resolution 22]

Answer B
                                   If (waterway = river) then
                                               name = * & is_in(natural, sea, any) = true    [0x18 resolution 22]
End if

Joris Bo

mkgmap-dev mailing list
mkgmap-dev at lists.mkgmap.org.uk

More information about the mkgmap-dev mailing list