abrensch / brouter

configurable OSM offline router with elevation awareness, Java + Android
MIT License
487 stars 115 forks source link

Profile-Compiler: constant expressions optimizations #566

Open abrensch opened 1 year ago

abrensch commented 1 year ago

Profile-Compiler: constant expressions optimizations

Currently the Profile-Compiler (BExpressionContext.parseFile) creates an (ordered) list of "expression trees" that are not optimized further.

However, chances are that major subtrees always evaluate to a constant value - they can be replaced by that constant value at compile time.

Focus here is not such much the runtime-cost of traversing these constant subtrees - this runtime cost is low as long as the number of distinct tag-value sets is low thus profile evaluation works mainly from the profile-cache.

So the focus of this issue here is to keep the number of distinct tag-value sets low by marking as much tagnames as possible as "unused" (in the sense of "processUnusedTags = false". So the compiler should be able o mark a tagname as unused though it is used inside a constant subtree.

This optimization is neccecary in order to integrate the new pseudo-tags in the standard profiles without creating a performance impact.

Example for such constant subtrees:

assign consider_town = false

assign town_penalty switch consider_town switch estimated_town_class= 0 switch estimated_town_class=1 0.5 switch estimated_town_class=2 0.9 switch estimated_town_class=3 1.2 switch estimated_town_class=4 1.3 switch estimated_town_class=5 1.4 switch estimated_town_class=6 1.6 99 0

Here, the compiler should at least be able to mark "estimated_town_class" as unused.

Second level would be to alse replace the expression by:

assign town_penalty = 0

and third level is to replace also the usage:

add town_penalty XY

by just:

XY

afischerdev commented 1 year ago

@abrensch OK, I saw it. And will start with that. But in the next few weeks my time is a bit limited.

abrensch commented 1 year ago

OK, I saw it. And will start with that. But in the next few weeks my time is a bit limited.

Sorry, assignig to you was just by accident. I will look into it, but commit via merge request and welcome a review by you. It's easy to introduce subtle bugs. When looking into the code, I already realized there might by a glitch with numerically evaluated tags not leading to marking the tag as "used".

afischerdev commented 1 year ago

I add a small new logic for global expressions. Please see my repo profile-compiler It removes the unused tags from messages list.

abrensch commented 1 year ago

I created a merge request for my patch: https://github.com/abrensch/brouter/pull/573

quaelnix commented 1 year ago

Would the "second level" catch this?

assign townpenalty
    switch estimated_town_class=   switch highway=residential 1.5 1.0
    switch estimated_town_class=1  1.5
    switch estimated_town_class=2  1.8
    switch estimated_town_class=3  2.4
    switch estimated_town_class=4  2.6
    switch estimated_town_class=5  2.8
    switch estimated_town_class=6  3.0 1

assign costfactor
    multiply switch consider_towns townpenalty 1
    ...
abrensch commented 1 year ago

Would the "second level" catch this?

No. I thought about detecting such assigned variables that are effectively unused, but that's difficult because there's also this remote access from the node context to the way-context ( "add way:townpenalty .." ) and it's hard to cover each edge-case so better keep it simple..