Python代码比Java慢60倍

Python代码比Java慢60倍,java,python,performance,numpy,numba,Java,Python,Performance,Numpy,Numba,此代码执行哈弗森距离计算,是更大项目的一部分 Java实现似乎比Python快60倍。它们的实现几乎相同 此性能在同一台机器和操作系统上。我尝试过各种组合: 操作系统:Linux和Windows 具有不同CPU的机器(第4代和第6代的i5) 但执行速度的差异是一致的 Python实现: Java实现: 产出: Java运行时间=229毫秒 Python运行时间=15.028019428253174秒 我可以提高Python的性能吗 你想要多快?一个装饰师,你可以得到6倍的加速 如果您有大量这样的

此代码执行哈弗森距离计算,是更大项目的一部分

Java实现似乎比Python快60倍。它们的实现几乎相同

此性能在同一台机器和操作系统上。我尝试过各种组合:

  • 操作系统:Linux和Windows
  • 具有不同CPU的机器(第4代和第6代的i5)
  • 但执行速度的差异是一致的

    Python实现: Java实现: 产出:

    Java运行时间=229毫秒

    Python运行时间=15.028019428253174秒


    我可以提高Python的性能吗

    你想要多快?一个装饰师,你可以得到6倍的加速

    如果您有大量这样的工作要做,那么numexpr或其他numpy方法可能会更快。所以,这取决于你需要它做什么

    from numba import jit
    
    @jit(nopython=true)
    def havershine ....
    

    存在两大瓶颈:

    • 环路
    • 函数调用(haversine函数和math函数)
    如果您在阵列上使用和操作,您只需调用函数一次,因为循环在阵列上矢量化-结果代码在我的计算机上运行速度快30倍(代码取自但经过更改,因此可以与numpy阵列一起使用):

    但这会创建很多巨大的临时数组,您可以避免使用它们,并且仍然使用数学函数:

    from math import radians, sin, cos, sqrt, asin
    from numba import njit
    
    @njit
    def haversine(lat1, lon1, lat2, lon2):
    
        R = 6372.8 # Earth radius in kilometers
    
        dLat = radians(lat2 - lat1)
        dLon = radians(lon2 - lon1)
        lat1 = radians(lat1)
        lat2 = radians(lat2)
    
        a = sin(dLat/2)**2 + cos(lat1)*cos(lat2)*sin(dLon/2)**2
        c = 2*asin(sqrt(a))
    
        return R * c
    
    @njit
    def haversine_loop():
        res = np.empty(10*1000*1000, dtype=np.float_)
        for x in range(0, 10*1000*1000): 
            res[x] = haversine(36.12, -86.67, 33.94, -118.40)
        return res
    
    haversine_loop()
    

    这实际上比numpy代码提高了50倍(因此最终要快150倍)。但是您需要检查这种方法在您的情况下是否可行(numba不是轻量级依赖!)。

    好的,Java被编译成字节码,而python是解释语言。如果您想让python更快,您应该考虑使用
    numpy
    库并将计算矢量化。看见希望纯Python与任何编译语言竞争都是徒劳的,这表明它在多个领域与Java相比都是失败的。它们用于不同的事情。我投票将此问题作为离题题来结束,因为带有工作代码以提高代码速度或效率的问题属于CodeReview.StackExchange。堆栈溢出适用于有关代码的问题,这些代码在某种程度上不起作用。@Prune我在问题或注释中没有看到OP询问为什么速度较慢的地方。OP中我看到的唯一问题是“可以改变一些东西来提高Python性能吗?”@TylerH:我明白了;我对整个主旨的解释。。。还有我的错误,我相信。我坐在篱笆上就这样了;我是第四次投票结束。谢谢,我会尝试这些改变。30次*50次=1500次。。。。所以最后一个代码比TS提供的代码快1500倍?@wmac-Oups-这似乎是我的错误。我以后再查一下这些数字。谢谢你提起这件事。
    Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32
    
    java version "1.8.0_131"
    Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
    Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
    
    from numba import jit
    
    @jit(nopython=true)
    def havershine ....
    
    import numpy as np
    
    R = 6372.8 # Earth radius in kilometers
    
    def haversine(lat1, lon1, lat2, lon2):
        dLat = np.radians(lat2 - lat1)
        dLon = np.radians(lon2 - lon1)
        lat1 = np.radians(lat1)
        lat2 = np.radians(lat2)
        sinLat = np.sin(dLat/2)
        sinLon = np.sin(dLon/2)
    
        a = sinLat * sinLat + np.cos(lat1) * np.cos(lat2) * sinLon * sinLon
        c = 2 * np.arcsin(np.sqrt(a))
    
        return R * c
    
    haversine(np.ones(10000000) * 36.12,
              np.ones(10000000) * -86.67,
              np.ones(10000000) * 33.94,
              np.ones(10000000) * -118.40)
    
    from math import radians, sin, cos, sqrt, asin
    from numba import njit
    
    @njit
    def haversine(lat1, lon1, lat2, lon2):
    
        R = 6372.8 # Earth radius in kilometers
    
        dLat = radians(lat2 - lat1)
        dLon = radians(lon2 - lon1)
        lat1 = radians(lat1)
        lat2 = radians(lat2)
    
        a = sin(dLat/2)**2 + cos(lat1)*cos(lat2)*sin(dLon/2)**2
        c = 2*asin(sqrt(a))
    
        return R * c
    
    @njit
    def haversine_loop():
        res = np.empty(10*1000*1000, dtype=np.float_)
        for x in range(0, 10*1000*1000): 
            res[x] = haversine(36.12, -86.67, 33.94, -118.40)
        return res
    
    haversine_loop()