diff --git a/ci/test_notebooks.sh b/ci/test_notebooks.sh index 577928768..457650d78 100755 --- a/ci/test_notebooks.sh +++ b/ci/test_notebooks.sh @@ -34,7 +34,7 @@ pushd notebooks # Add notebooks that should be skipped here # (space-separated list of filenames without paths) -SKIPNBS="" +SKIPNBS="binary_predicates.ipynb cuproj_benchmark.ipynb" EXITCODE=0 trap "EXITCODE=1" ERR diff --git a/notebooks/binary_predicates.ipynb b/notebooks/binary_predicates.ipynb new file mode 100644 index 000000000..b398fec62 --- /dev/null +++ b/notebooks/binary_predicates.ipynb @@ -0,0 +1,950 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "12084de2-e6cf-4759-9478-c0777672562d", + "metadata": {}, + "source": [ + "# cuSpatial Binary Predicates Demo\n", + "\n", + "The following notebook exercises nine binary predicates available in cuSpatial:\n", + "\n", + "- contains\n", + "- geom_equals\n", + "- intersects\n", + "- covers\n", + "- crosses\n", + "- disjoint\n", + "- overlaps\n", + "- touches\n", + "- within\n", + "\n", + "The inputs are loaded from a large set of fundamental feature relationships implemented in `binpred_test_dispatch`." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "5a0464f6-6c53-420c-97f7-407534700fef", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import cuspatial\n", + "import numpy as np\n", + "import time\n", + "import geopandas\n", + "from shapely.geometry import GeometryCollection\n", + "from cuspatial.testing.test_geometries import (\n", + " features,\n", + " point_point_dispatch_list,\n", + " point_linestring_dispatch_list,\n", + " point_polygon_dispatch_list,\n", + " linestring_linestring_dispatch_list,\n", + " linestring_polygon_dispatch_list,\n", + " polygon_polygon_dispatch_list\n", + ")\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib.ticker as ticker\n", + "import ipywidgets as widgets" + ] + }, + { + "cell_type": "markdown", + "id": "e1d3a030-bed7-41e3-8cb0-cf12fef134bb", + "metadata": { + "tags": [] + }, + "source": [ + "All of the feature pairs that are used in cuSpatial's binary predicate test functions are contained in `features`, a dictionary of named feature pairs with shapely geometries as values. Each of the `dispatch_list` objects contains a list of the feature names that are used in testing binary predicates." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b995412-610f-4d02-816a-fcbaf9044355", + "metadata": {}, + "outputs": [], + "source": [ + "# Create a gridded output so that we can visualize all of the features used in this benchmark\n", + "def show_feature_table(features, width=6):\n", + " columns = [widgets.Output() for _ in range(len(features))]\n", + " for i in range(len(columns)):\n", + " with columns[i]:\n", + " display(GeometryCollection(features[i]))\n", + " rows = [columns[i:i + width] for i in range(0, len(columns), width)]\n", + " [display(widgets.HBox(row)) for row in rows]" + ] + }, + { + "cell_type": "markdown", + "id": "8777be86-a889-4472-a8a5-3a6356093a04", + "metadata": {}, + "source": [ + "## Point-Point Relationships\n", + "\n", + "The following cell displays the features that are used in Point+Point predicates in this notebook:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3bf3b3eb-79f0-4e75-85dd-d7a43a3a4df4", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f5cef8dbf0ba4bc0aa5078fd44bd48c8", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "show_feature_table([features[feature][1:3] for feature in point_point_dispatch_list])\n", + "print(len(point_point_dispatch_list))" + ] + }, + { + "cell_type": "markdown", + "id": "ac9a6f51-85aa-4db1-a45f-3735ed6418e1", + "metadata": {}, + "source": [ + "The binary predicates for Point-Point relationships all depend on whether or not the Points being compared are equal or unequal. Testing binary predicates for Point-Point relationships then depends on only two input pairs: Point equals Point and Point does not equal Point. The left output above shows two equal points, the right shows two-inequal points. The length of `point_point_dispatch_list` is 2.\n", + "\n", + "## Point-LineString Relationships\n", + "\n", + "The following cell displays the features that are used in Point+LineString predicates:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a3c3ad83-12cd-4105-9cc8-15700b1c24a6", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "36e52a9f6b1e4780868b0618914aa5d0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n" + ] + } + ], + "source": [ + "show_feature_table([features[feature][1:3] for feature in point_linestring_dispatch_list])\n", + "print(len(point_linestring_dispatch_list))" + ] + }, + { + "cell_type": "markdown", + "id": "6c19d249-dced-4bad-9434-3c82015570d6", + "metadata": {}, + "source": [ + "There are three relationships that a Point can have with a LineString: Disjoint, Point is equal to one of the LineString boundary points, and point falls between the LineString boundary points.\n", + "\n", + "## Point-Polygon Relationships\n", + "\n", + "The next cell demonstrates the four ways that a Point can relate with a Polygon:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "037417d9-9024-4522-923b-bc99dc2dd1fb", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "50c3e6cebcc247ba8d4a903d59138ba1", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output(), Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n" + ] + } + ], + "source": [ + "show_feature_table([features[feature][1:3] for feature in point_polygon_dispatch_list])\n", + "print(len(point_polygon_dispatch_list))" + ] + }, + { + "cell_type": "markdown", + "id": "29e564d2-f028-4d7d-bf10-89b08112528c", + "metadata": {}, + "source": [ + "One additional relationship exists between a Point and a Polygon. A Point can:\n", + "- Fall outside of the Polygon\n", + "- Share a coordinate with the Polygon\n", + "- Fall along the boundary of the Polygon\n", + "- Fall in the interior of the Polygon\n", + "\n", + "This exhausts the ways that a Point can relate with another feature type. Next we must look at the ways that a LineString can relate with other feature types.\n", + "\n", + "## LineString-LineString Relationships\n", + "\n", + "The following cell demonstrates the ways that two LineStrings can relate:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "26f49388-935f-4c38-a2e4-6cbb07c1456e", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "93ea7aae845945818ce8c5b961e676f5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output(), Output(), Output(), Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "50fe586cc76c4195a5e2b6ca0fd2381f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output(), Output(), Output(), Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12\n" + ] + } + ], + "source": [ + "show_feature_table([features[feature][1:3] for feature in linestring_linestring_dispatch_list])\n", + "print(len(linestring_linestring_dispatch_list))" + ] + }, + { + "cell_type": "markdown", + "id": "d9bbb9a7-fbd0-42db-a663-99b5e40bd9bd", + "metadata": { + "tags": [] + }, + "source": [ + "These relationships are:\n", + "- disjoint\n", + "- equal\n", + "- overlaps (interior)\n", + "- share outer boundary point\n", + "- share inner boundary point\n", + "- touch along edge\n", + "- touch multiple times along edge\n", + "- crosses\n", + "\n", + "## LineString-Polygon Relationships\n", + "\n", + "The following cell demonstrates the relationships that can exist between a LineString and a Polygon:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ac85c54a-52bc-424c-a12b-3f29ccc93c78", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f4f78d79527b45f38414bde0b624a5e3", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output(), Output(), Output(), Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "bb24c01a58844121bbdc9a7dfcbc86d4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output(), Output(), Output(), Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5a60ee484365451493b9e98255637393", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output(), Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "16\n" + ] + } + ], + "source": [ + "show_feature_table([features[feature][1:3] for feature in linestring_polygon_dispatch_list])\n", + "print(len(linestring_polygon_dispatch_list))" + ] + }, + { + "cell_type": "markdown", + "id": "eeb10f00-87e9-43bb-afeb-e0d13250832a", + "metadata": { + "tags": [] + }, + "source": [ + "These relationships are:\n", + "- disjoint\n", + "- touch polygon point\n", + "- touch polygon edge\n", + "- overlap polygon edge\n", + "- partially overlap polygon edge\n", + "- overlap inner edge\n", + "- cross from point to point\n", + "- cross from edge to edge\n", + "- within\n", + "- cross from exterior coordinates\n", + "\n", + "I noticed one is missing that can be added to cuSpatial's predicate tests: cross from point to edge\n", + "\n", + "## Polygon-Polygon Relationships\n", + "\n", + "The following cell demonstrates the relationships that can exist between two Polygons:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "e46df3ab-896d-4d22-aaf0-46e2345d951a", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1ffa19716a6244509f8b9be9d3c530bf", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output(), Output(), Output(), Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "798c938721b64b41a1ab24cf01f0527b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Output(), Output(), Output(), Output(), Output()))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "11\n" + ] + } + ], + "source": [ + "show_feature_table([features[feature][1:3] for feature in polygon_polygon_dispatch_list])\n", + "print(len(polygon_polygon_dispatch_list))" + ] + }, + { + "cell_type": "markdown", + "id": "432075b2-3c65-4a06-a4ae-a9f8fdac3927", + "metadata": {}, + "source": [ + "The names of these relationships are defined in `polygon_polygon_dispatch_list`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "248f8f31-b2a7-4dd0-b861-df1755f17ef0", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "polygon-polygon-disjoint\n", + "polygon-polygon-touch-point\n", + "polygon-polygon-touch-edge\n", + "polygon-polygon-overlap-edge\n", + "polygon-polygon-overlap-inside-edge\n", + "polygon-polygon-point-inside\n", + "polygon-polygon-point-outside\n", + "polygon-polygon-in-out-point\n", + "polygon-polygon-in-point-point\n", + "polygon-polygon-contained\n", + "polygon-polygon-same\n" + ] + } + ], + "source": [ + "_ = [print(name) for name in polygon_polygon_dispatch_list]" + ] + }, + { + "cell_type": "markdown", + "id": "99f2f743-34e6-4ea7-8fcc-8ad31a183ac5", + "metadata": {}, + "source": [ + "cuSpatial's implementation of binary predicates creates `GeoSeries` objects comprised of these shapes and their relationships, then uses a combination of the three basic predicates _point_in_polygon_, _intersects_, and _equals_ to compute results for the nine predicates listed above, comparing our results with the result of the same operation performed by `GeoPandas/Shapely`.\n", + "\n", + "Following are the functions used for benchmarking and comparisons with geopandas." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "515799dc-1a93-4e20-a3a7-499d1870e95d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def sample_test_data(features, dispatch_list, size, lib=cuspatial):\n", + " \"\"\"Creates either a cuspatial or geopandas GeoSeries object using the\n", + " Feature objects in `features`, the list of features to sample from in\n", + " `dispatch_list`, and the size of the resultant GeoSeries.\n", + " \"\"\"\n", + " geometry_tuples = [features[key][1:3] for key in dispatch_list]\n", + " geometries = [\n", + " [lhs_geo for lhs_geo, _ in geometry_tuples],\n", + " [rhs_geo for _, rhs_geo in geometry_tuples]\n", + " ]\n", + " lhs = lib.GeoSeries(list(geometries[0]))\n", + " rhs = lib.GeoSeries(list(geometries[1]))\n", + " np.random.seed(0)\n", + " lhs_picks = np.random.randint(0, len(lhs), size)\n", + " rhs_picks = np.random.randint(0, len(rhs), size)\n", + " return (\n", + " lhs[lhs_picks].reset_index(drop=True),\n", + " rhs[rhs_picks].reset_index(drop=True)\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "d3d32f9d-a485-4490-a27d-a1770d061939", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def benchmark(features, dispatch_list, predicate, size, lib):\n", + " \"\"\"Times the speed of producing the test data as well as the predicate execution.\n", + " \"\"\"\n", + " (lhs, rhs) = sample_test_data(features, dispatch_list, size, lib)\n", + " fn = getattr(lhs, predicate)\n", + " predicate = time.time()\n", + " cuspatial_result = fn(rhs)\n", + " return size / (time.time() - predicate)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "733485f5-5058-4b8b-8f74-a6000ef999d0", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def benchmark_dispatch_list(dispatch_list, size, engines, predicates):\n", + " \"\"\"Returns a dictionary object of benchmark times for all of the\n", + " predicates of the form:\n", + " {\n", + " \"contains\": (\n", + " [geopandas_predicate_time],\n", + " [cuspatial_predicate_time],\n", + " ),\n", + " \"geom_equals\": (\n", + " [geopandas_predicate_time],\n", + " [cuspatial_predicate_time],\n", + " ),\n", + " ...\n", + " }\n", + " \"\"\"\n", + " return {predicate: [\n", + " benchmark(\n", + " features, dispatch_list, predicate, size, engine\n", + " ) for engine in engines] for predicate in predicates\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "817df6de-eb75-4139-9821-35b4704a2db6", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "\"\"\"List of engines and predicates to test.\"\"\"\n", + "engines = [geopandas, cuspatial]\n", + "predicates = [\n", + " 'contains',\n", + " 'geom_equals',\n", + " 'intersects',\n", + " 'covers',\n", + " 'crosses',\n", + " 'disjoint',\n", + " 'overlaps',\n", + " 'touches',\n", + " 'within'\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "046c4599-5cde-4151-9558-d018f1077f35", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "\"\"\"Chart rendering functions\"\"\"\n", + "def plot_grouped_bars(results_dict, title):\n", + " values = np.array(list(results_dict.values()))\n", + " x = np.arange(len(predicates)) # The label locations\n", + " width = 0.35 # The width of the bars\n", + "\n", + " fig, ax = plt.subplots()\n", + "\n", + " # Plot bars\n", + " rects1 = ax.bar(x - width/2, values[:,0], width, label='GeoPandas', color='#36c9dd')\n", + " rects2 = ax.bar(x + width/2, values[:,1], width, label='cuSpatial', color='#7400ff')\n", + "\n", + " # Add text for labels, title, custom x-axis tick labels, and legend\n", + " ax.set_ylabel('Binops per Second')\n", + " ax.set_yscale('log')\n", + " ax.set_title(title)\n", + " ax.set_xticks(x)\n", + " ax.set_xticklabels(predicates)\n", + " ax.legend()\n", + "\n", + " fig.tight_layout()\n", + " plt.xticks(rotation=45)\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "3a45dff0-161d-4e6d-80c0-b480d9bdde00", + "metadata": {}, + "source": [ + "# Benchmarking Results\n", + "\n", + "The following cells demonstrate cuSpatial's binary predicate performance against GeoPandas for all of the features and groups of features defined in the various `dispatch_list` files. The size of each test is designed to keep execution time ~1-2m at most, so that results can be explored and displayed dynamically.\n", + "\n", + "# Point+Point Benchmarks" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "30cfa962-8370-4433-9fe4-111a25e19163", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "size = 1_000_000\n", + "point_point_results = benchmark_dispatch_list(\n", + " point_point_dispatch_list,\n", + " size,\n", + " engines,\n", + " predicates \n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "837f7c31-e8cb-4c9e-84fe-305cdad8898b", + "metadata": {}, + "source": [ + "`point_point_results` contains the execution time for geopandas and cuspatial predicates using only `Points`. The performance gap continues to increase as the number of elements increases, until cuspatial `.loc` based indexing causes OOM errors around 200m Points." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "3d2edb5b-9ebb-4cf6-9eab-3d73a4b550c2", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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uXMHAPD8+XPs2LEDt27dwv3793Hs2DEcPnz4W24CERERkUHQe7CrX78+Jk6ciObNm3/w/tmzZ6Nbt27o3r07ihUrhjlz5sDR0RG//vorAGDv3r1wcXFB9uzZYWVlhYYNG36yj11MTAwiIyO1/hEREREZA70Hu0+JjY3FyZMnUadOHa3lderUwbFjxwAAjo6OOHbsGKKjo5GQkICDBw+iSJEiH33OKVOmwMbGRvnn6OiYqttARERE9K0YdLB7+vQpEhISYG9vr7Xc3t4e4eHhAIBy5cqhQYMGKFmyJEqUKIGCBQvCx8fno885bNgwvHz5Uvl39+7dVN0GIiIiom8lTYyKValUWrdFRGvZpEmTMGnSpGQ9l4WFBSwsLFK0PiIiIiJDYNAtdjly5ECGDBmU1jmNx48fJ2nFIyIiIkrvDDrYmZubw8vLC8HBwVrLg4ODUaFCBT1VRURERGSY9H4qNioqCtevX1du37x5E2fOnEH27NmRL18+DBgwAB06dIC3tzfKly+PxYsX486dO+jVq5ceqyYiIiIyPHoPdidOnED16tWV2wMGDAAAdOrUCcuXL0ebNm0QERGB8ePH4+HDhyhevDiCgoKQP39+fZVMREREZJD0HuyqVasGEfnkOn369EGfPn2+UUVEREREaZNB97FLTf7+/nB1dUXp0qX1XQoRERFRiki3wc7X1xdhYWE4fvy4vkshIiIiShHpNtgRERERGRsGOyIiIiIjwWBHREREZCQY7IiIiIiMBIMdERERkZFgsCMiIiIyEuk22HEeOyIiIjI26TbYcR47IiIiMjbpNtgRERERGRsGOyIiIiIjwWBHREREZCQY7IiIiIiMBIMdERERkZFgsCMiIiIyEgx2REREREYi3QY7TlBMRERExibdBjtOUExERETGJt0GOyIiIiJjw2BHREREZCQY7IiIiIiMBIMdERERkZFgsCMiIiIyEgx2REREREaCwY6IiIjISDDYERERERkJBjsiIiIiI5Fugx0vKUZERETGJt0GO15SjIiIiIxNug12RERERMaGwY6IiIjISDDYERERERkJBjsiIiIiI8FgR0RERGQkGOyIiIiIjASDHREREZGRYLAjIiIiMhIMdkRERERGgsGOiIiIyEik22DHa8USERGRsTHVdwH64uvrC19fX0RGRsLGxkbf5VA6N1iV8s85Q1L+OYmIyLCl2xY7IiIiImOTrBa7bdu2JfsJfXx8vrgYIjJubJkkIkpdyQp2TZs21bqtUqkgIlq3NRISElKmMiKkfBBgCCAiImOWrFOxarVa+bdnzx54enpi165dePHiBV6+fImgoCCUKlUKu3fvTu16iYiIiOgjdB480a9fPyxcuBCVKlVSltWtWxfW1tbo0aMHLl26lKIFEhEREVHy6Dx44saNGx8cRWpjY4Nbt26lRE1ERERE9AV0DnalS5dGv3798PDhQ2VZeHg4Bg4ciDJlyqRocURERESUfDoHu2XLluHx48fInz8/XFxc4OLignz58uHhw4dYunRpatRIRERERMmgcx87FxcXnDt3DsHBwbh8+TJEBK6urqhVq5bW6FgiIiIi+ra+6MoTKpUKderUQZ06dVK6HiIiIiL6Ql8U7Pbt24d9+/bh8ePHUKvVWvctW7YsRQojIiIiIt3oHOzGjRuH8ePHw9vbG7lz5+bpVyIiIiIDoXOwW7hwIZYvX44OHTqkRj1ERERE9IV0HhUbGxuLChUqpEYtRERERPQVdA523bt3x59//pkatXxT/v7+cHV1RenSpfVdChEREVGK0PlUbHR0NBYvXoy9e/eiRIkSMDMz07p/9uzZKVZcavL19YWvry8iIyM/eCUNIiIiorRG52B37tw5eHp6AgAuXLigdR8HUhARERHpj87B7sCBA6lRBxERERF9JZ372L3r3r17uH//fkrVQkRERERfQedgp1arMX78eNjY2CB//vzIly8fsmbNigkTJiSZrJiIiIiIvh2dT8WOGDECS5cuxdSpU1GxYkWICI4ePYqxY8ciOjoakyZNSo06iYiIiOgzdA52K1aswG+//QYfHx9lmYeHB/LmzYs+ffow2BERERHpic6nYp89e4aiRYsmWV60aFE8e/YsRYoiIiIiIt3pHOw8PDywYMGCJMsXLFgADw+PFCmKiIiIiHSn86nY6dOno2HDhti7dy/Kly8PlUqFY8eO4e7duwgKCkqNGomIiIgoGXRusatatSquXLmCZs2a4cWLF3j27BmaN2+OK1euoHLlyqlRIxERERElg84tdgCQN29eDpIgIiIiMjA6t9j9/vvv2LBhQ5LlGzZswIoVK1KkKCIiIiLSnc7BburUqciRI0eS5XZ2dpg8eXKKFEVEREREutM52N2+fRvOzs5JlufPnx937txJkaKIiIiISHc6Bzs7OzucO3cuyfKzZ8/C1tY2RYoiIiIiIt3pHOzatm2Lvn374sCBA0hISEBCQgL279+Pn3/+GW3btk2NGomIiIgoGXQeFTtx4kTcvn0bNWvWhKlp4sPVajU6duzIPnZEREREeqRzsDM3N8e6deswYcIEnD17FlZWVnB3d0f+/PlTo75U4+/vD39/fyQkJOi7FCIiIqIU8UXz2AGAk5MTRAQFCxZUWu7SEl9fX/j6+iIyMhI2Njb6LoeIiIjoq+ncx+7Nmzfo1q0brK2t4ebmpoyE7du3L6ZOnZriBRIRERFR8ugc7IYNG4azZ8/i4MGDsLS0VJbXqlUL69atS9HiiIiIiCj5dD6HGhgYiHXr1qFcuXJQqVTKcldXV9y4cSNFiyMiIsM1WPX5dXQ1Q1L+OYnSE51b7J48eQI7O7sky1+/fq0V9IiIiIjo29I52JUuXRo7d+5UbmvC3JIlS1C+fPmUq4yIiIiIdKLzqdgpU6agXr16CAsLQ3x8PObOnYuLFy8iJCQEhw4dSo0aiYiIiCgZdG6xq1ChAo4ePYo3b96gYMGC2LNnD+zt7RESEgIvL6/UqJGIiIiIkuGLJqBzd3fHihUrUroWIiIiIvoKyQ52arUaarVaazLiR48eYeHChXj9+jV8fHxQqVKlVCmSiIiIiD4v2cGuW7duMDMzw+LFiwEAr169QunSpREdHY3cuXPjl19+wdatW9GgQYNUK5aIiIiIPi7ZfeyOHj2Kli1bKrdXrlyJ+Ph4XLt2DWfPnsWAAQMwY8aMVCmSiIiIiD4v2cHu/v37KFSokHJ73759aNGihXKd1U6dOuHixYspXyERERERJUuyg52lpSXevn2r3A4NDUW5cuW07o+KikrZ6oiIiIgo2ZLdx87DwwN//PEHpkyZgr///huPHj1CjRo1lPtv3LiBPHnypEqRlFRKX8qHl/EhIiJK+5Id7EaNGoUGDRpg/fr1ePjwITp37ozcuXMr92/ZsgUVK1ZMlSKJiIiI6POSHeyqV6+OkydPIjg4GLly5UKrVq207vf09ESZMmVSvEAiIiIiSh6dJih2dXWFq6vrB+/r0aNHihRERERERF9G50uKEREREZFhYrAjIiIiMhIMdkRERERGQqdgl5CQgEOHDuH58+epVQ8RERERfSGdgl2GDBlQt25dvHjxIpXKISIiIqIvpfOpWHd3d/z333+pUQsRERERfQWdg92kSZMwaNAg7NixAw8fPkRkZKTWPyIiIiLSD53msQOAevXqAQB8fHygUv3vulYiApVKhYSEhJSrjoiIiIiSTedgd+DAgdSog4iIiIi+ks7BrmrVqqlRxzfn7+8Pf39/tjASERGR0dA52AHA33//jUWLFuG///7Dhg0bkDdvXvzxxx9wdnZGpUqVUrrGVOHr6wtfX19ERkbCxsZG3+UQERHRNzBY9fl1dDVDUv45v5TOgyc2bdqEunXrwsrKCqdOnUJMTAwA4NWrV5g8eXKKF0hEREREyaNzsJs4cSIWLlyIJUuWwMzMTFleoUIFnDp1KkWLIyIiIqLk0znYXblyBVWqVEmyPEuWLJy4mIiIiEiPdA52uXPnxvXr15MsP3LkCAoUKJAiRRERERGR7nQOdj179sTPP/+Mf/75ByqVCg8ePMDq1asxaNAg9OnTJzVqJCIiIqJk0HlUrJ+fH16+fInq1asjOjoaVapUgYWFBQYNGoQff/wxNWokIiIiomT4oulOJk2ahBEjRiAsLAxqtRqurq7IlClTStdGRERERDr4omAHANbW1rC3t4dKpWKoIyIiIjIAOvexi4+Px6hRo2BjYwMnJyfkz58fNjY2GDlyJOLi4lKjRiIiIiJKBp1b7H788Uds2bIF06dPR/ny5QEAISEhGDt2LJ4+fYqFCxemeJFERERE9Hk6B7s1a9Zg7dq1qF+/vrKsRIkSyJcvH9q2bctgR0RERKQnOp+KtbS0hJOTU5LlTk5OMDc3T4maiIiIiOgL6BzsfH19MWHCBOUasQAQExODSZMmcboTIiIiIj3S+VTs6dOnsW/fPjg4OMDDwwMAcPbsWcTGxqJmzZpo3ry5su7mzZtTrlIiIiIi+iSdg13WrFnRokULrWWOjo4pVhARERERfRmdg93vv/+eGnUQERER0VfSuY8dERERERkmBjsiIiIiI8FgR0RERGQkGOyIiIiIjESKBLsXL16kxNMQERER0VfQOdhNmzYN69atU263bt0atra2yJs3L86ePZuixRERERFR8ukc7BYtWqTMWxccHIzg4GDs2rUL9evXx+DBg1O8QCIiIiJKHp3nsXv48KES7Hbs2IHWrVujTp06cHJyQtmyZVO8QCIiIiJKHp1b7LJly4a7d+8CAHbv3o1atWoBAEQECQkJKVsdERERESWbzi12zZs3R/v27VGoUCFERESgfv36AIAzZ87AxcUlxQskIiIiouTROdj98ssvcHJywt27dzF9+nRkypQJQOIp2j59+qR4gURERESUPDoHOzMzMwwaNCjJ8n79+qVEPURERET0hXQOdgBw5coVzJ8/H5cuXYJKpULRokXx008/oUiRIildHxERERElk86DJzZu3IjixYvj5MmT8PDwQIkSJXDq1CkUL14cGzZsSI0aiYiIiCgZdG6x8/Pzw7BhwzB+/Hit5WPGjMGQIUPQqlWrFCuOiIiIiJJP5xa78PBwdOzYMcny77//HuHh4SlSFBERERHpTudgV61aNfz9999Jlh85cgSVK1dOkaKIiIiISHc6n4r18fHBkCFDcPLkSZQrVw4AEBoaig0bNmDcuHHYtm2b1rpERERE9G3oHOw0c9UFBAQgICDgg/cBgEql4pUoiIiIiL4hnYOdWq1OjTqIiIiI6Cvp3MeOiIiIiAzTFwW7Q4cOoXHjxnBxcUGhQoXg4+PzwQEVRERERPTt6BzsVq1ahVq1asHa2hp9+/bFjz/+CCsrK9SsWRN//vlnatRIRERERMmgcx+7SZMmYfr06ejfv7+y7Oeff8bs2bMxYcIEtG/fPkULJCIiIqLk0bnF7r///kPjxo2TLPfx8cHNmzdTpChdXLlyBZ6enso/KysrBAYGfvM6iIiIiPRN5xY7R0dH7Nu3Dy4uLlrL9+3bB0dHxxQrLLmKFCmCM2fOAACioqLg5OSE2rVrf/M6iIiIiPRN52A3cOBA9O3bF2fOnEGFChWgUqlw5MgRLF++HHPnzk2NGpNt27ZtqFmzJjJmzKjXOoiIiIj0QedTsb1798batWtx/vx59OvXDz///DMuXLiAdevWoWfPnjoXcPjwYTRu3Bh58uSBSqX64GnUgIAAODs7w9LSEl5eXh8dgbt+/Xq0adNG5xqIiIiIjMEXTXfSrFkzHDlyBBEREYiIiMCRI0fQpEmTLyrg9evX8PDwwIIFCz54/7p169CvXz+MGDECp0+fRuXKlVG/fn3cuXNHa73IyEgcPXoUDRo0+KI6iIiIiNI6nU/FasTGxuLx48dJrkSRL18+nZ6nfv36qF+//kfvnz17Nrp164bu3bsDAObMmYO//voLv/76K6ZMmaKst3XrVtStWxeWlpaf/HsxMTGIiYlRbkdGRupULxEREZGh0rnF7tq1a6hcuTKsrKyQP39+ODs7w9nZGU5OTnB2dk7R4mJjY3Hy5EnUqVNHa3mdOnVw7NgxrWXJPQ07ZcoU2NjYKP/0MeCDiIiIKDXo3GLXuXNnmJqaYseOHcidOzdUKlVq1AUAePr0KRISEmBvb6+13N7eHuHh4crtly9f4t9//8WmTZs++5zDhg3DgAEDlNuRkZEMd0RERGQUdA52Z86cwcmTJ1G0aNHUqOeD3g+PIqK1zMbGBo8ePUrWc1lYWMDCwiJF6yMiIiIyBDqfinV1dcXTp09To5YkcuTIgQwZMmi1zgHA48ePk7TiEREREaV3Oge7adOmwc/PDwcPHkRERAQiIyO1/qUkc3NzeHl5ITg4WGt5cHAwKlSokKJ/i4iIiCit0/lUbK1atQAANWvW1FquOT2akJCg0/NFRUXh+vXryu2bN2/izJkzyJ49O/Lly4cBAwagQ4cO8Pb2Rvny5bF48WLcuXMHvXr10rV0IiIiIqOmc7A7cOBAihZw4sQJVK9eXbmtGdjQqVMnLF++HG3atEFERATGjx+Phw8fonjx4ggKCkL+/PlTtA4iIiKitE7nYFe1atUULaBatWoQkU+u06dPH/Tp0ydF/66/vz/8/f11bmEkIiIiMlTJCnbnzp1D8eLFYWJignPnzn1y3RIlSqRIYanN19cXvr6+iIyMhI2Njb7LISIiIvpqyQp2np6eCA8Ph52dHTw9PaFSqT7YyvYlfeyIiIiIKGUkK9jdvHkTOXPmVP6fiIiIiAxPsoLduwMVOGiBiIiIyDDpPHgiIiICtra2AIC7d+9iyZIlePv2LXx8fFC5cuUUL5CIiIiIkifZExSfP38eTk5OsLOzQ9GiRXHmzBmULl0av/zyCxYvXozq1asjMDAwFUslIiIiok9JdrDz8/ODu7s7Dh06hGrVqqFRo0Zo0KABXr58iefPn6Nnz56YOnVqatZKRERERJ+Q7FOxx48fx/79+1GiRAl4enpi8eLF6NOnD0xMErPhTz/9hHLlyqVaoSmN89gRERGRsUl2i92zZ8+QK1cuAECmTJmQMWNGZM+eXbk/W7ZsePXqVcpXmEp8fX0RFhaG48eP67sUIiIiohSR7GAHJM5T96nbRERERKQ/Oo2K7dy5MywsLAAA0dHR6NWrFzJmzAgAiImJSfnqiIiIiCjZkh3sOnXqpHX7+++/T7JOx44dv74iIiIiIvoiyQ52v//+e2rWQURERERfSac+dkRERERkuBjsiIiIiIwEgx0RERGRkWCwIyIiIjIS6TbY+fv7w9XVFaVLl9Z3KUREREQpIt0GO155goiIiIxNug12RERERMaGwY6IiIjISDDYERERERkJBjsiIiIiI8FgR0RERGQkGOyIiIiIjASDHREREZGRYLAjIiIiMhLpNtjxyhNERERkbNJtsOOVJ4iIiMjYpNtgR0RERGRsGOyIiIiIjASDHREREZGRYLAjIiIiMhIMdkRERERGgsGOiIiIyEgw2BEREREZCQY7IiIiIiPBYEdERERkJBjsiIiIiIwEgx0RERGRkUi3wc7f3x+urq4oXbq0vkshIiIiShHpNtj5+voiLCwMx48f13cpRERERCki3QY7IiIiImPDYEdERERkJBjsiIiIiIwEgx0RERGRkWCwIyIiIjISDHZERERERoLBjoiIiMhIMNgRERERGQkGOyIiIiIjwWBHREREZCQY7IiIiIiMBIMdERERkZFgsCMiIiIyEuk22Pn7+8PV1RWlS5fWdylEREREKSLdBjtfX1+EhYXh+PHj+i6FiIiIKEWk22BHREREZGwY7IiIiIiMBIMdERERkZFgsCMiIiIyEgx2REREREaCwY6IiIjISDDYERERERkJBjsiIiIiI8FgR0RERGQkGOyIiIiIjASDHREREZGRYLAjIiIiMhIMdkRERERGgsGOiIiIyEgw2BEREREZCQY7IiIiIiPBYEdERERkJBjsiIiIiIxEug12/v7+cHV1RenSpfVdChEREVGKSLfBztfXF2FhYTh+/Li+SyEiIiJKEek22BEREREZGwY7IiIiIiPBYEdERERkJBjsiIiIiIwEgx0RERGRkWCwIyIiIjISDHZERERERoLBjoiIiMhIMNgRERERGQkGOyIiIiIjwWBHREREZCQY7IiIiIiMBIMdERERkZFgsCMiIiIyEgx2REREREaCwY6IiIjISDDYERERERkJBjsiIiIiI8FgR0RERGQkGOyIiIiIjASDHREREZGRYLAjIiIiMhIMdkRERERGgsGOiIiIyEgw2BEREREZCQY7IiIiIiORboOdv78/XF1dUbp0aX2XQkRERJQi0m2w8/X1RVhYGI4fP67vUoiIiIhSRLoNdkRERETGhsGOiIiIyEgw2BEREREZCQY7IiIiIiPBYEdERERkJBjsiIiIiIwEgx0RERGRkWCwIyIiIjISDHZERERERoLBjoiIiMhIMNgRERERGQkGOyIiIiIjwWBHREREZCQY7IiIiIiMBIMdERERkZFgsCMiIiIyEgx2REREREaCwY6IiIjISJjqu4D0ouy//6Xo81VBgRR9PqL0jJ9PIjIWDHZERGRUGNSNC99P3TDYUYpKLx/A9LKdRESUtrCPHREREZGRYIsdEX0UWyaNC99PIuPHFjsiIiIiI8FgR0RERGQkGOyIiIiIjASDHREREZGR4OAJIiKiNIiDYehD2GJHREREZCQY7IiIiIiMBIMdERERkZFgsCMiIiIyEgx2REREREaCwY6IiIjISDDYERERERkJBjsiIiIiI8FgR0RERGQkGOyIiIiIjASDHREREZGRYLAjIiIiMhIMdkRERERGgsGOiIiIyEgw2BEREREZCQY7IiIiIiNhqu8C9E1EAACRkZGp+ncSol6l6PPFIGXrTanN53Z+mZTeTiBltpXb+WW4nV+O25l83M4vY6jb+ennT/wDmszyKSpJzlpG7N69e3B0dNR3GURERESfdPfuXTg4OHxynXQf7NRqNR48eIDMmTNDpVLpu5xkiYyMhKOjI+7evYssWbLou5xUw+00LtxO48LtNC7cTsMmInj16hXy5MkDE5NP96JL96diTUxMPpt+DVWWLFnS1I75pbidxoXbaVy4ncaF22m4bGxskrUeB08QERERGQkGOyIiIiIjwWCXBllYWGDMmDGwsLDQdympittpXLidxoXbaVy4ncYj3Q+eICIiIjIWbLEjIiIiMhIMdkRERERGgsGOiIiIyEgw2BEREREZCQY7IiL6JhISEvRdApHRY7BL5zgoOhFfB8PG9yfti42NRYYMGQAAz58/13M1RMaLwS6d0XxB3r59G8+fP08z18dNTWq1Wnkd2KJgWCIiIgAg3eynERERePPmjb7LSHHBwcGYM2cOAKB3795o06YN4uPj9VvUN6BWq5X/f/v2rR4rSR2a75NLly7h/Pnzeq4m5Xzoh+S776WhY7BLR0QEKpUKW7duxffff4+1a9ca5cFGF2q1Wrmg8owZM+Dn55dmv1g1B6O7d+8iJiZGz9V8vaCgIPz4448ICgrSdynfxPbt29G1a1ccPHgQ0dHR+i4nxSQkJGDt2rVY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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_grouped_bars(point_point_results, 'Point-Point Binops: Log(10) Ops/Second')" + ] + }, + { + "cell_type": "markdown", + "id": "33e6de84-5f01-4856-aee6-72a2cb12b923", + "metadata": {}, + "source": [ + "# Point+LineString Binops Benchmarks\n", + "\n", + "Noteworthy in the Point+LineString benchmark sets are the three predicates with the same execution time as GeoPandas: `contains`, `geom_equals`, and `covers`. This is because these predicates are all impossible, and each library simply terminates immediately returning `False` apparently based on the feature type.\n", + "\n", + "Also noteworthy are `crosses` and `overlaps` which cuSpatial demonstrates a massive performance increase. This is either because our algorithm for determining these predicates is more efficient than GeoPandas, or incorrect." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0023d764-f632-4ee4-9fb7-1c223d428399", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "size = 10_000_000\n", + "point_linestring_results = benchmark_dispatch_list(\n", + " point_linestring_dispatch_list,\n", + " size,\n", + " engines,\n", + " predicates\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "c8a5067e-be86-460e-9a5b-92d71d6ad990", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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nQCQEydOKH8pt/02aWmxGzduXKqWwKJFi4q9vb24ubnJqlWrZM+ePdK+fXsBIIcPH1bWi4yMFAcHBylatKgsWrRI9u3bJ5MmTRJTU1Pp3r27st7vv/8uAOTbb7+VvXv3yr59+2ThwoUycOBAERF5+PCh0roRGBio7N/Dhw+V/ShQoIA4ODjIzz//LAcPHlTq+NjHVERk0aJFAkDatm0rO3bskN9++01KliwpRYsWlaJFi773cUv5+L5580bevHkjL1++lL/++kvKly8vxYoV03p+NK+lmzdvat3eyspKSpQoIQsXLpSQkBDp37+/AJCVK1cq6z18+FCKFCkihQoVkoULF8ru3btlwIABAkD69euXat8dHBykVq1asnHjRvnjjz/E09NTjI2N5fjx48q6TZo0kUKFCsnixYvl0KFDsmXLFhk7dqysXbtWWefgwYMCQMaNG/fBxyItLXaa57hz586yc+dOWbVqlRQrVkwsLS3l33//VdZLz/NSrFgx6dChw3vv930tdgsXLhQAcunSpVTXVa5cWapXr55quaurq7Rp0+a993n8+HEBICNGjHjnOi9evBAjIyNp0qSJskzzmihcuLD89NNPsmfPHhk4cKAAED8/P2W9D72nNO7cuSMqlUr27t2rLHNxcZE8efLI7Nmz5fLly6JWq99aX1JSkjRt2lRy584tEyZMkJCQEFm6dKkUKVJE3Nzc5NWrV8q6mqMYbdq0kT/++EP27t0rc+bMkTFjxijrpPX579atm5iYmIirq6vMmjVL9u3bJ2PHjhWVSiUTJkxQ1nv16pW4urqKpaWl/Pzzz8pj5ejoyBa7LIDBjnRC82UcGhoqb968kRcvXsiOHTukUKFCkidPHomKipLdu3cLAJkxY4bWbdetW6eEP413hZBy5cpJYmKisvzkyZMCQH7//XdlWWYdin1XsDMzM5Pbt28ry16/fi0FChSQvn37Ksv69u0rFhYWWuuJJB+uSvllOWDAAMmXL99763jfl2/dunUFgOzfv/+t133MY5qUlCS2trZStWpVre3dvn1bjI2N0xzsAKT6K1mypFy+fFlr3XcFOwDy119/aa3r5uam9WX//fffv3W9fv36iUqlkitXrmjte+HCheX169fKejExMVKgQAFp2LChsszCwkIGDRr03v07dOiQ5MiRQ+vL9F0+FOyePn0q5ubm0qxZM63lERERYmpqKl26dBGR9D0vDx48eOehzpTe99qaMmWKAJDIyMhU1zVu3FhKliyZavmXX34pNjY2773PtWvXCgBZuHDhe9ezsbERV1dX5bLmNbF161at9b7++msxMjJS3mtpeU+JiMydO1fy588vb968UZadPHlSCT8AJE+ePNKiRQtZtWqVVsjThMeNGzdqbTMsLEwASFBQkIiI3LhxQ3LkyCFffvnlO+tI6/MvkvxaAiDr16/XWrdZs2ZSqlQp5fKCBQve+Vgx2Ok/HoolnapWrRqMjY2RJ08etGjRAra2tti1axdsbGxw4MABAMmHD1Jq3749cufOneoQ2Ns0b94cOXLkUC6XL18eAFKNrHwbtVqNxMRE5e+/h2s+loeHBxwdHZXLZmZmKFmypFZNO3bsQL169VC4cGGtGry9vQEAhw8fBgBUqVIFz549Q+fOnbF161Y8fvw43fXkz58f9evXT/P6H3pMr1y5gqioKHTo0EHrdo6OjqhZs2aa76d48eIICwtDWFgYTpw4gTVr1sDc3BwNGjTA1atXP3h7W1tbVKlSRWtZ+fLltR7nAwcOwM3NLdV63bt3h4gor0GNNm3awMzMTLmcJ08etGzZEkeOHFFeH1WqVMGKFSswefJkhIaG4s2bN6lqq1u3LhITEzF27NgPPxAfcOLECbx+/TrV+8TBwQH169dX3ifpeV7u378PALC2tv7k+t41Mvxty62trfHw4cNU3Q0+hoikuo88efLAx8dHa1mXLl2gVqtx5MgRAGl/T23cuBGtWrVCzpw5lWWenp64du0adu/ejZEjR6J69erYv38/fH194ePjAxEBkPz+zpcvH1q2bKn1/vbw8ICtra0yyjgkJARJSUnw8/N7536m9fnXUKlUaNmypday/74vDh48+M7HivQfgx3p1KpVqxAWFoazZ8/i/v37uHDhgvIlEx0djZw5c6JQoUJat1GpVLC1tUV0dPQHt29lZaV12dTUFADw+vXrD962Z8+eMDY2Vv4+NAIwrf5bk6aulDU9ePAA27dv17p/Y2NjlClTBgCUL5uuXbti+fLluH37Ntq2bQtra2tUrVoVISEhaa4nvaNJP/SYap4XGxubVLd927J30fRhq1y5MqpVq4bOnTtj165diIyMTFMgSsvjHB0d/db9L1y4sNa+aNja2qZa19bWFgkJCcoUHuvWrUO3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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_grouped_bars(point_linestring_results, 'Point-Linestring Binops: Log(10) Ops/Second')" + ] + }, + { + "cell_type": "markdown", + "id": "72ca19c3-7975-4170-b211-c01581edc4c8", + "metadata": {}, + "source": [ + "# Point-Polygon Benchmarks\n", + "\n", + "Point+Polygon binops produce mixed results. See the graphs and speedup factor listed below.\n", + "\n", + "- `contains`, `geom_equals`, and `covers` have the same result as with Point+LineString: they are impossible, and terminated without a binop.\n", + "- `intersection`: Take note of intersection here because Point+Polygon intersection is computed via Point+Polygon `.contains`, which demonstrates the biggest issue with our implementations of point-in-polygon and requires that we develop further optimizations. `quadtree_point_in_polygon` computes the relationship of every point in the rhs with every point in the lhs. The possible result matrix with 10m rows is of course 10mx10m, which cannot fit in memory. In order to use quadtree, the polygons need to have an indexing step to eliminate duplicates at least. `brute_force_point_in_polygon` only supports up to 31 polygons at a time, so handling a dataset of this size would require 10_000_000/31=322580 iterations. Because of these limitations, I have enabled `pairwise_point_in_polygon` to support the basic pairwise implementation of `.contains` as it is represented in GeoPandas. Unfortunately, while it supports the necessary data size, performance is inferior. Performance is inferior as a combination of the unoptimized speed of `pairwise_point_in_polygon` and the expensive indexing techniques designed to support, primarily, `quadtree_point_in_polygon`. The easiest optimization is to handle indexing differently for `pairwise_point_in_polygon`, since expensive and complicated techniques are not required for `Polygon.contains(Point)`. This doesn't solve the issue of indexing for more complicated geometry types. We will see this result repeat itself throughout the benchmarks.\n", + "- `disjoint`: Contains an inefficiency based on calling `pairwise_linestring_intersection` that should be removed by the time you read this document in the containing pull request.\n", + "- `within`: Within is the inverse of `.intersects` here and suffers from the same performance limitations." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "8fe862b1-7af0-43e7-ba57-0f620448d5b9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "size = 10_000_000\n", + "point_polygon_results = benchmark_dispatch_list(\n", + " point_polygon_dispatch_list,\n", + " size,\n", + " engines,\n", + " predicates\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "c0eac545-24e7-49b0-bc19-4b451251852f", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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S5fQsmVLPHv2DE+ePEGrVq1w6dIlVK9ePSNqJCIiIqJUSHOLHQAULlw40x8kwVOKEX1cxX//S9ft1UCxdN0eERFpS3OL3a+//ooNGzakWL5hwwasWLEiXYr6Evz8/BAREYHw8HBdl0JERESULtIc7KZPn478+fOnWG5tbY2pU6emS1FERERElHZpDnY3b96Eo6NjiuVFixbFrVu30qUoIiIiIkq7NAc7a2trnDlzJsXy06dPw8rKKl2KIiIiIqK0S/PBEx06dMDAgQORK1cu1KhRAwBw4MABDBo0CB06dEj3Ailz4WB7IiIi3UlzsJs8eTJu3ryJunXrwtg46eZqtRpdunThGDsiIiIiHUpzsDM1NcW6deswadIknD59GtmzZ4erqyuKFi2aEfURERERUSp90jx2AODg4AARQfHixZWWOyIiIiLSnTQnslevXuHbb79V5qy7fPkyihUrhoEDB8LW1hbff/99uhdpCDj2jIiIiDJamo+KDQgIwOnTp7F//36Ym5sry+vVq4d169ala3FERERElHppbrELDg7GunXrUKlSJahUKmW5i4sLrl27lq7FEREREVHqpbnF7tGjR7C2tk6x/OXLl1pBj4iIiIi+rDQHO29vb+zYsUO5rAlzS5YsQeXKldOvMiIiIiJKkzR3xU6bNg2NGjVCREQEEhISMH/+fJw/fx5Hjx7FgQMHMqLGDBEYGIjAwEAkJibquhQiIiKidJHmFrsqVarg77//xqtXr1C8eHHs2rULNjY2OHr0KLy8vDKixgzh5+eHiIgIhIeH67oUIiIionTxSRPQubq6KtOdEBEREZF+SHWwU6vVUKvVWpMRP3jwAAsXLsTLly/h6+uLatWqZUiRRERERPRxqQ52PXv2hImJCRYvXgwAePHiBby9vREbG4tChQrhhx9+wB9//IHGjRtnWLFERERE9H6pHmP3999/o02bNsrllStXIiEhAVeuXMHp06cxdOhQzJo1K0OKJCIiIqKPS3Wwu3v3LkqUKKFc3rNnD1q3bg1LS0sAQNeuXXH+/Pn0r5CIiIiIUiXVwc7c3ByvX79WLoeFhaFSpUpa18fExKRvdURERESUaqkOdu7u7li1ahUA4NChQ3jw4AHq1KmjXH/t2jXY2tqmf4VERERElCqpPnhizJgxaNy4MdavX4/79++jW7duKFSokHL9li1bULVq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98LNzQ0eHh5YvHgx+vfvDyOjpGz47bffolKlShlWKBERERF9WKpb7J48eYKCBQsCAHLmzIkcOXIgX758yvV58+bFixcv0r9CIiIiIkqVVAc7IGmeug9dzkwCAwPh4uICb29vXZdCRERElC7SdFRst27dYGZmBgCIjY1F3759kSNHDgBAXFxc+leXgThBMRERERmaVAe7rl27al3++uuvU6zTpUuXz6+IiIiIiD5JqoPdr7/+mpF1EBEREdFnStMYOyIiIiLSXwx2RERERAaCwY6IiIjIQDDYERERERkIBjsiIiIiA8FgR0RERGQgGOyIiIiIDESWDXY8pRgREREZmiwb7Pz8/BAREYHw8HBdl0JERESULrJssCMiIiIyNAx2RERERAaCwY6IiIjIQDDYERERERkIBjsiIiIiA8FgR0RERGQgGOyIiIiIDASDHREREZGBYLAjIiIiMhAMdkREREQGgsGOiIiIyEAw2BEREREZiCwb7AIDA+Hi4gJvb29dl0JERESULrJssPPz80NERATCw8N1XQoRERFRusiywY6IiIjI0DDYERERERkIBjsiIiIiA8FgR0RERGQgGOyIiIiIDASDHREREZGBYLAjIiIiMhAMdkREREQGgsGOiIiIyEAw2BEREREZCAY7IiIiIgPBYEdERERkIBjsiIiIiAwEgx0RERGRgWCwIyIiIjIQDHZEREREBoLBjoiIiMhAZNlgFxgYCBcXF3h7e+u6FCIiIqJ0kWWDnZ+fHyIiIhAeHq7rUoiIiIjSRZYNdkRERESGhsGOiIiIyEAw2BEREREZCAY7IiIiIgPBYEdERERkIBjsiIiIiAwEgx0RERGRgWCwIyIiIjIQDHZEREREBoLBjoiIiMhAMNgRERERGQgGOyIiIiIDwWBHREREZCAY7IiIiIgMBIMdERERkYFgsCMiIiIyEAx2RERERAaCwY6IiIjIQDDYERERERkIBjsiIiIiA8FgR0RERGQgGOyIiIiIDASDHREREZGBYLAjIiIiMhAMdkREREQGwiCC3fXr11G7dm24uLjA1dUVL1++1HVJRERERF+csa4LSA/dunXD5MmTUb16dTx58gRmZma6LomIiIjoi8v0we78+fMwMTFB9erVAQD58uXTcUVEREREuqHzrtiDBw+iWbNmsLW1hUqlQnBwcIp1goKC4OjoCHNzc3h5eeHQoUPKdVeuXEHOnDnh6+uLcuXKYerUqV+weiIiIiL9ofNg9/LlS7i7u2PBggXvvH7dunUYPHgwRo0ahZMnT6J69erw8fHBrVu3AABv3rzBoUOHEBgYiKNHjyI0NBShoaFfcheIiIiI9ILOg52Pjw8mT56MVq1avfP6uXPnomfPnujVqxecnZ0xb948FClSBD///DMAwM7ODt7e3ihSpAjMzMzQuHFjnDp16r33FxcXh+joaK0/IiIiIkOg82D3IfHx8Th+/DgaNGigtbxBgwY4cuQIAMDb2xsPHjzA06dPoVarcfDgQTg7O793m9OmTYOlpaXyV6RIkQzdByIiIqIvRa+D3ePHj5GYmAgbGxut5TY2NoiMjAQAGBsbY+rUqahRowbc3NxQokQJNG3a9L3bDAgIwPPnz5W/27dvZ+g+EBEREX0pmeKoWJVKpXVZRLSW+fj4wMfHJ1XbMjMz43QoREREZJD0usUuf/78yJYtm9I6p/Hw4cMUrXhEREREWZ1eBztTU1N4eXmlOMo1NDQUVapU0VFVRERERPpJ512xMTExuHr1qnL5+vXrOHXqFPLlywd7e3sMHToUnTt3Rvny5VG5cmUsXrwYt27dQt++fXVYNREREZH+0XmwO3bsGGrXrq1cHjp0KACga9euWL58Odq3b4+oqChMnDgR9+/fR9myZRESEoKiRYt+1v0GBgYiMDAQiYmJn7UdIiIiIn2h82BXq1YtiMgH1+nfvz/69++frvfr5+cHPz8/REdHw9LSMl23TURERKQLej3GjoiIiIhSj8GOiIiIyEAw2BEREREZiCwb7AIDA+Hi4gJvb29dl0JERESULrJssPPz80NERATCw8N1XQoRERFRusiywY6IiIjI0DDYERERERkIBjsiIiIiA6HzCYqJiIiIvpThqvTf5qwPn2fhi2KLHREREZGByLLBjtOdEBERkaHJsl2xPFcs6RND7xogIqIvI8u22BEREREZGgY7IiIiIgPBYEdERERkIBjsiIiIiAwEgx0RERGRgciywY7TnRAREZGhybLBzs/PDxEREQgPD9d1KURERETpIssGOyIiIiJDw2BHREREZCAY7IiIiIgMBIMdERERkYFgsCMiIiIyEAx2RERERAaCwY6IiIjIQGTZYMcJiomIiMjQZNlgxwmKiYiIyNBk2WBHREREZGgY7IiIiIgM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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_grouped_bars(point_polygon_results, 'Point-Polygon Binops: Log(10) Ops/Second')" + ] + }, + { + "cell_type": "markdown", + "id": "43083a6d-eb2c-4a99-8076-41ea018806e3", + "metadata": {}, + "source": [ + "# LineString-LineString Benchmarks\n", + "\n", + "LineString results vary but all are largely satisfactory - this is due to the lack of an unoptimized `point_in_polygon` occurring in any of the operations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "785289d0-5b7a-4a26-9a9f-82091aa34153", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "size = 10_000_000\n", + "linestring_linestring_results = benchmark_dispatch_list(\n", + " linestring_linestring_dispatch_list,\n", + " size,\n", + " engines,\n", + " predicates\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ee3f26c4-3668-4505-8428-df002046fc26", + "metadata": {}, + "outputs": [], + "source": [ + "plot_grouped_bars(linestring_linestring_results, 'LineString-LineString Binops: Log(10) Ops/Second')" + ] + }, + { + "cell_type": "markdown", + "id": "c5503871-b7ba-47d7-bd80-1532833f9204", + "metadata": { + "tags": [] + }, + "source": [ + "# LineString-Polygon Benchmarks\n", + "\n", + "- `intersects` and `within` use a combination of intersection and point_in_polygon and the results are unsatisfying. There are likely performance improvements that can be made in the python implementation of intersection which would close the gap, but the underlying problem with `point_in_polygon` remains." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ae206b14-f1b9-49d2-8575-ddec9ac7a6f2", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "size = 5_000_000\n", + "linestring_polygon_results = benchmark_dispatch_list(\n", + " linestring_polygon_dispatch_list,\n", + " size,\n", + " engines,\n", + " predicates\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0373c7d7-7448-4860-9681-ed8b4aa8cdcb", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "plot_grouped_bars(linestring_polygon_results, 'LineString-Polygon Binops: Log(10) Ops/Second')" + ] + }, + { + "cell_type": "markdown", + "id": "bcf8e6d8-1098-4e52-a2c5-47ac12739da3", + "metadata": {}, + "source": [ + "# Polygon-Polygon Benchmarks\n", + "\n", + "Performance is better with cuspatial than geopandas for many predicates, but not so much better that it is a really compelling use case. That's with the exception of `crosses` whose comparative performance is so astronomical that it suggests there may be an implementation issue." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1c04e79-d029-45f9-8f8d-01d1b652cd95", + "metadata": {}, + "outputs": [], + "source": [ + "size = 5_000_000\n", + "polygon_polygon_results = benchmark_dispatch_list(\n", + " polygon_polygon_dispatch_list,\n", + " size,\n", + " engines,\n", + " predicates\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3abd06db-5f3a-41b2-97f4-2f72e52dc48e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "plot_grouped_bars(polygon_polygon_results, 'Polygon+Polygon Binops: Log(10) Ops/Second')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43a892cc-c6f9-43b8-b860-a01c45cbc8d3", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}