对标 cuSpatial#
本仓库中基准测试的目标是衡量各种 cuSpatial API 的性能。cuSpatial 中的基准测试使用 pytest-benchmark
插件编写,该插件基于 pytest
Python 测试框架。使用 pytest-benchmark
为熟悉 pytest
的开发者提供了无缝的体验。我们包含了公共 API 和内部函数的基准测试。前者提供了我们性能的宏观视图,尤其是与 geopandas 相比。后者帮助我们量化并最小化 Python 绑定的开销。
注意
我们目前的基准测试完全侧重于测量运行时间。然而,对于某些情况,最小化内存占用同样重要。未来,我们可能会更新基准测试,以包含内存使用测量。
基准测试组织#
顶层基准测试分为 internal
和 API
目录。API 基准测试用于用户期望使用的公共功能。内部基准测试衡量 cuSpatial 内部构件的性能,这些构件没有稳定性保证。
在每个目录中,基准测试根据函数类型进行组织。cuSpatial 中的函数通常分为两类:
如
GeoDataFrame
或GeoSeries
等类的方法。对上述类进行操作的自由函数,如
cuspatial.from_geopandas
。
前者应组织到名为 bench_class.py
的文件中。例如,GeoDataFrame.sjoin
的基准测试属于 API/bench_geodataframe.py
。基准测试应尽可能以类层次结构的最高层级进行编写。例如,所有类都支持 take
方法,因此这些基准测试属于 API/bench_frame_or_index.py
。
注意
pytest
不支持存在两个同名的基准测试文件,即使它们位于不同的目录中。因此,公共类的内部方法的基准测试文件会以 _internal
为后缀。例如,GeoDataFrame.polygons.xy
的基准测试属于 internal/bench_geodataframe_internal.py
。
自由函数具有更大的灵活性。总的来说,它们应该被分组到包含相似功能的基准测试文件中。例如,I/O 基准测试都可以放在 io/bench_io.py
中。目前这些分组由开发者自行决定。
运行基准测试#
默认情况下,pytest 会发现以 test_
为前缀的测试文件和函数。对于基准测试,我们将 pytest
配置为使用 bench_
前缀进行搜索。安装 pytest-benchmark
后,运行基准测试就像直接运行 pytest
一样简单。
当运行基准测试时,默认行为是将结果以表格形式输出到终端。一个常见的需求是比较更改前后的基准测试性能。我们可以使用 pytest 的 --benchmark-autosave
选项保存输出,从而生成这些比较。使用此选项时,基准测试运行后,输出中将包含一行
Saved benchmark data in: /path/to/XXXX_*.json
XXXX
是一个四位数字,用于标识基准测试。如果愿意,用户也可以使用 --benchmark-save=NAME
选项,它允许对结果文件名进行更多控制。给定两次基准测试运行 XXXX
和 YYYY
,可以使用以下命令比较基准测试:
pytest-benchmark compare XXXX YYYY
请注意,比较使用的是 pytest-benchmark
命令而不是 pytest
命令。pytest-benchmark
有许多额外的选项可用于自定义输出。下一行包含一个有用的示例,但开发者应进行实验以找到有用的输出方式
pytest-benchmark compare XXXX YYYY --sort="name" --columns=Mean --name=short --group-by=param
更多详细信息,请参阅 pytest-benchmark
文档。
基准测试内容#
编写基准测试#
就像基准测试应该以层次结构中最高层级的类来编写一样,它们也应该尽可能少地假定数据的性质。
与 geopandas 比较#
随着 cuSpatial API 的成熟,我们将从性能角度将其与匹配的 geopandas 函数进行比较。
测试基准测试#
基准测试需要与 cuspatial 中的 API 更改保持同步更新。当前的基准测试集是针对一小组测试数据的调试基准测试。我们的 CI 测试利用这一点来确保基准测试仍然是有效的代码。
性能分析#
虽然并非严格属于我们的基准测试套件,但性能分析是一个常见的需求,因此我们在此提供一些指南。以下是两种简单的(可能有其他)对基准测试进行性能分析的方法:
pytest-profiling
插件。py-spy
包。
使用前者就像在 pytest
调用中添加 --profile
(或 --profile-svg
) 参数一样简单。后者则需要从 py-spy 调用 pytest,如下所示:
py-spy record -- pytest bench_foo.py
每种工具都有不同的优势,并提供略有不同的信息。开发者应该尝试这两种工具,看看哪种更适合特定的工作流程。也鼓励开发者分享他们发现的有用的替代方法。