首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pybind11比纯Python慢

Pybind11比纯Python慢
EN

Stack Overflow用户
提问于 2022-08-26 11:12:22
回答 1查看 291关注 0票数 0

我使用pybind11创建了Python绑定。一切都很完美,但当我做speed check test时,结果令人失望。

基本上,我在C++中有一个函数,它添加了两个数字,我想从一个Python脚本中使用这个函数。我还包括了一个for循环,可以运行100次,以便更好地查看处理时间的差异。

对于从C++“导入”函数,使用pybind11,我获得:0.002310514450073242 ~ 0.0034799575805664062

对于简单的Python脚本,我获得:0.0012788772583007812 ~ 0.0015883445739746094

main.cpp文件:

代码语言:javascript
复制
#include <pybind11/pybind11.h>
namespace py = pybind11;

double sum(double a, double b) {
    return a + b;
}

PYBIND11_MODULE(SumFunction, var) {
    var.doc() = "pybind11 example module";
    var.def("sum", &sum, "This function adds two input numbers");
}

main.py文件:

代码语言:javascript
复制
from build.SumFunction import *
import time

start = time.time()
for i in range(100):
    print(sum(2.3,5.2))
end = time.time()

print(end - start)

CMakeLists.txt文件:

代码语言:javascript
复制
cmake_minimum_required(VERSION 3.0.0)
project(Projectpybind11 VERSION 0.1.0)

include(CTest)
enable_testing()

add_subdirectory(pybind11)
pybind11_add_module(SumFunction main.cpp)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

简单Python脚本:

代码语言:javascript
复制
import time

def summ(a,b):
        return a+b
start = time.time()
for i in range(100):
        print(summ(2.3,5.2))
end = time.time()

print(end - start)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-26 16:00:38

  1. 标杆是一件非常复杂的事情,甚至可以称为系统工程

因为有很多过程会干扰我们的基准工作。例如:网卡中断响应/键盘或鼠标输入/操作系统调度.我遇到了我的生产过程被操作系统阻止多达15秒!因此,正如其他顾问所指出的那样,print()调用了更多不必要的干扰。

  1. 您的测试计算太简单了。

你必须把它想清楚,你在比较什么。Python和C++之间传递参数的速度显然比在Python方面慢。因此,我假设您希望比较两者的计算速度,而不是参数传递速度。如果是这样的话,我认为你的计算代码太简单了,这会导致我们计算的时间主要是通过are的时间,而计算的时间只是总数的次要部分。所以,我把我的样本放在下面,我很高兴看到有人来润色它。--

  1. 您的循环计数太少了。

循环越少,随机性越强。与我的观点1相似,测试时间仅为0.000x秒。运行过程有可能受到操作系统的干扰。我认为我们应该让测试时间至少持续几秒钟。

  1. C++并不总是比Python快。现在有那么多Python模块/libs可以使用GPU执行大量的计算,甚至只能通过CPU并行地执行矩阵操作。我猜您可能正在评估是否在项目中使用Pybind11。我认为这样的比较毫无价值,因为什么是最好的工具取决于什么是真正的要求,但这是一个很好的教训,以学习的东西。我最近遇到了一个案例,Python在深度学习中比C++更快。哈哈,好笑吗?

最后,我在我的PC上运行我的示例,发现C++的计算速度比用Python快100倍。我希望这对你有帮助。如果有人愿意修改/纠正我的意见,这是我的荣幸!

请原谅我丑陋的英语,我希望我已经正确地表达了一些事情。

ComplexCpp.cpp:

代码语言:javascript
复制
#include <cmath>
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;

double Compute( double x, py::array_t<double> ys ) {
//  std::cout << "x:" << std::setprecision( 16 ) << x << std::endl;
    auto r = ys.unchecked<1>();
    for( py::ssize_t i = 0; i < r.shape( 0 ); ++i ) {
        double y = r( i );
//      std::cout << "y:" << std::setprecision( 16 ) << y << std::endl;
        x += y;
        x *= y;
        y = std::max( y, 1.001 );
        x /= y;
        x *= std::log( y );
    }
    return x;
};

PYBIND11_MODULE( ComplexCpp, m ) {
    m.def( "Compute", &Compute, "a more complicated computing" );
};

tryComplexCpp.py

代码语言:javascript
复制
import ComplexCpp
import math
import numpy as np
import random
import time


def PyCompute(x: float, ys: np.ndarray) -> float:
    #print(f'x:{x}')
    for y in ys:
        #print(f'y:{y}')
        x += y
        x *= y
        y = max(y, 1.001)
        x /= y
        x *= math.log(y)
    return x


LOOPS: int = 100000000

if __name__ == "__main__":
    # initialize random
    x0 = random.random()

    """ We store all args in a array, then pass them into both C++ func and
        python side, to ensure that args for both sides are same. """
    args = np.ndarray(LOOPS, dtype=np.float64)
    for i in range(LOOPS):
        args[i] = random.random()

    print('Args are ready, now start...')

    # try it with C++
    start_time = time.time()
    x = ComplexCpp.Compute(x0, args)
    print(f'Computing with C++ in { time.time() - start_time }.\n')
    # forcely use the result to prevent the entire procedure be optimized(omit)
    print(f'The result is {x}\n')

    # try it with python
    start_time = time.time()
    x = PyCompute(x0, args)
    print(f'Computing with Python in { time.time() - start_time }.\n')
    # forcely use the result to prevent the entire procedure be optimized(omit)
    print(f'The result is {x}\n')
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73500145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档