Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cut the dijkstra_algorithm.py time in half with various tricks #15

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Mortal
Copy link

@Mortal Mortal commented May 1, 2023

Implement a number of performance optimizations that altogether cut down the running time to about half, as tested with a 2905 * 4029 raster with 1 start point and 1 end point.

  • Don't use queue.PriorityQueue, as it is a threadsafe queue with unnecessary locking - use heapq.heappush() and heappop() instead.

  • Don't use function calls - instead, inline all functions. Almost all the functions in the old code were only used in one place.

  • Instead of dicts and sets, use lists of lists, which have faster lookup.

  • Reduce the number of calls to feedback.setProgress().

Implement a number of performance optimizations that altogether
cut down the running time to about half, as tested with a 2905 * 4029
raster with 1 start point and 1 end point.

* Don't use queue.PriorityQueue, as it is a threadsafe queue with
  unnecessary locking - use heapq.heappush() and heappop() instead.

* Don't use function calls - instead, inline all functions.
  Almost all the functions in the old code were only used in one place.

* Instead of dicts and sets, use lists of lists, which have faster lookup.

* Reduce the number of calls to feedback.setProgress().
@Gooong
Copy link
Owner

Gooong commented Jun 16, 2023

Hi @Mortal, thanks for the improvement. Will review and test this PR and release soon!

@biship
Copy link

biship commented Jan 21, 2025

@Mortal

QGIS version: 3.40.2-Bratislava
QGIS code revision: 14826ca1
Qt version: 5.15.13
Python version: 3.12.8
GDAL version: 3.9.3
GEOS version: 3.13.0-CAPI-1.19.0
PROJ version: Rel. 9.5.0, September 15th, 2024
PDAL version: 2.8.1 (git-version: a06325)
Algorithm started at: 2025-01-21T10:06:15
Algorithm 'Least Cost Path' starting…
Input parameters:
{ 'BOOLEAN_FIND_LEAST_PATH_TO_ALL_ENDS' : False, 'BOOLEAN_OUTPUT_LINEAR_REFERENCE' : False, 'INPUT_COST_RASTER' : 'D:/Downloads/qgis/slope.tif', 'INPUT_END_LAYER' : 'end.shp', 'INPUT_RASTER_BAND' : 1, 'INPUT_START_LAYER' : 'start.shp', 'OUTPUT' : 'TEMPORARY_OUTPUT' }

The size of cost raster is: 6401 * 5378
Searching least cost path...
Traceback (most recent call last):
File "C:\Users/nick/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\leastcostpath\least_cost_path_algorithm.py", line 246, in processAlgorithm
result = dijkstra(start_tuple, end_tuples, matrix, find_nearest, feedback)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users/nick/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\leastcostpath\dijkstra_algorithm.py", line 90, in dijkstra
its += 1
^^^
UnboundLocalError: cannot access local variable 'its' where it is not associated with a value

Execution failed after 8.32 seconds

Loading resulting layers
Algorithm 'Least Cost Path' finished

@biship
Copy link

biship commented Jan 21, 2025

Commenting out line 90 (its), crashes QGIS. The PR doesn't work for me.

Python Stack Trace
Windows fatal exception: access violation

Current thread 0x000089e8 (most recent call first):
File "C:\Users/nick/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\leastcostpath\least_cost_path_algorithm.py", line 452 in block2matrix
matrix = [[None if block.isNoData(i, j) else block.value(i, j) for j in range(block.width())]
File "C:\Users/nick/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\leastcostpath\least_cost_path_algorithm.py", line 238 in processAlgorithm
matrix, contains_negative = MinCostPathHelper.block2matrix(block)

Thread 0x00007d7c (most recent call first):
File "C:\PROGRA1/QGIS/apps/qgis/./python/plugins\processing\ProcessingPlugin.py", line 509 in executeAlgorithm
dlg.exec()
File "C:\PROGRA
1/QGIS/apps/qgis/./python/plugins\processing\gui\ProcessingToolbox.py", line 272 in executeAlgorithm
self.executeWithGui.emit(alg.id(), self, self.in_place_mode, False)

Stack Trace

PyInit_sip :
PyInit_sip :
PyInit_sip :
pdal::PointView::layout :
PyLong_FromString :
PyObject_Vectorcall :
PyObject_Vectorcall :
PyEval_EvalFrameDefault :
PyFunction_Vectorcall :
PyArg_CheckPositional :
PyObject_Call :
PyObject_Call :
PyInit_sip :
PyInit_sip :
pdal::StreamPointTable::reset :
pdal::PointView::layout :
QgsProcessingAlgorithm::runPrepared :
QgsProcessingAlgRunnerTask::run :
pdal::PointView::layout :
QgsTask::start :
QThreadPoolPrivate::reset :
QThread::start :
BaseThreadInitThunk :
RtlUserThreadStart :

QGIS Info
QGIS Version: 3.40.2-Bratislava
QGIS code revision: 14826ca1
Compiled against Qt: 5.15.13
Running against Qt: 5.15.13
Compiled against GDAL: 3.9.3
Running against GDAL: 3.9.3

System Info
CPU Type: x86_64
Kernel Type: winnt
Kernel Version: 10.0.26100

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants