【发布时间】:2022-01-01 21:03:48
【问题描述】:
我向 python 暴露了一个 c++ unordered_map<string, int>,结果发现这个映射比 python 的 dict 慢 10 倍。
参见下面的代码。
// map.cpp file
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <string>
#include <unordered_map>
namespace py = pybind11;
PYBIND11_MAKE_OPAQUE(std::unordered_map<std::string, int>);
PYBIND11_MODULE(map, m) {
// map
py::bind_map<std::unordered_map<std::string, int>>(m, "MapStr2Int");
}
在 MacOS 上,用这个 cmd 编译它:
c++ -O3 -std=c++14 -shared -fPIC -Wl,-undefined,dynamic_lookup $(python3 -m pybind11 --includes) map.cpp -o map$(python3-config --extension-suffix)
最后对比一下ipython中的pythondict:
In [20]: import map
In [21]: c_dict = map.MapStr2Int()
In [22]: for i in range(100000):
...: c_dict[str(i)] = i
...:
In [23]: py_dict = {w:i for w,i in c_dict.items()}
In [24]: arr = [str(i) for i in np.random.randint(0,100000, 100)]
In [25]: %timeit [c_dict[w] for w in arr]
59 µs ± 2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [26]: %timeit [py_dict[w] for w in arr]
6.58 µs ± 87.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
正如所见,c_dict 比 python 版本 py_dict 慢得多。
为什么以及如何改进?
【问题讨论】:
-
不确定您的问题是什么?如果
std::unordered_map速度较慢,不要使用它? -
这似乎是 pybind11 的错,因为stackoverflow.com/questions/29268914/… 表明它们大致相等。在 pybind 的 github 上,您的问题已经提出了许多问题:github.com/pybind/pybind11/issues/1227 和 github.com/pybind/pybind11/issues/2005 等。如果这有帮助,请见谅
-
我希望 pybind11 需要分配新内存来构造
std::string对象以传递给unordered_map。 python版本不需要这样做。 -
@IainShelvington 不,我期待性能不会比 py 的 dict 慢,想知道我是否错过了任何技巧。
-
@Yolomep 感谢您的链接,看起来很相关。