代码之家  ›  专栏  ›  技术社区  ›  chase

在julia中尝试catch或类型转换性能-(julia 73秒,Python 0.5秒)

  •  3
  • chase  · 技术社区  · 11 年前

    我一直在玩Julia,因为它在语法上似乎类似于python(我喜欢),但声称速度更快。然而,我尝试制作一个类似于我在python中的脚本,用于测试数值在使用此函数的文本文件中的位置:

    function isFloat(s)
        try:
            float64(s)
            return true
        catch:
            return false
        end
    end
    

    由于某种原因,对于具有合理行数(约500000)的文本文件,这需要大量时间。
    为什么会这样?有更好的方法吗?我可以从中理解该语言的哪些一般特征以应用于其他语言?

    以下是我与时代一起运行的两个确切脚本,以供参考:

    python:约0.5秒

    def is_number(s):
        try:
            np.float64(s)
            return True
        except ValueError:
            return False
    
    start = time.time()
    file_data = open('SMW100.asc').readlines()
    file_data = map(lambda line: line.rstrip('\n').replace(',',' ').split(), file_data)
    
    bools = [(all(map(is_number, x)), x) for x in file_data]
    print time.time() - start
    

    朱莉娅:约73.5秒

    start = time()
    function isFloat(s)
        try:
            float64(s)
            return true
        catch:
            return false
        end
    end
    x = map(x-> split(replace(x, ",", " ")), open(readlines, "SMW100.asc"))
    
    u = [(all(map(isFloat, i)), i) for i in x]
    
    print(start - time())
    
    3 回复  |  直到 11 年前
        1
  •  7
  •   Steven G. Johnson    11 年前

    还请注意,您可以使用 float64_isvalid 函数,以(a)检查字符串是否为有效的浮点值,(b)返回该值。

    还要注意,冒号( : )之后 try catch 在您的 isFloat Julia的代码是错误的(这是一种Python主义)。

    更快的代码版本应该是:

    const isFloat2_out = [1.0]
    isFloat2(s::String) = float64_isvalid(s, isFloat2_out)
    
    function foo(L)
        x = split(L, ",")
        (all(isFloat2, x), x)
    end
    
    u = map(foo, open(readlines, "SMW100.asc"))
    

    在我的机器上,对于一个包含100000行和10列数据(其中50%是有效数字)的示例文件,Python代码需要4.21秒,Julia代码需要2.45秒。

        2
  •  5
  •   John Myles White    11 年前

    这是一个有趣的性能问题,可能值得提交给julia用户,以获得比SO可能提供的更集中的反馈。乍一看,我认为你遇到了问题,因为(1)try/catch开始时速度稍慢,然后(2)你使用try/catch的环境中存在大量类型不确定性,因为很多函数调用不返回稳定类型。因此,Julia解释器花费时间试图找出对象的类型,而不是进行计算。很难说清楚大瓶颈在哪里,因为你做了很多在朱莉娅不太习惯的事情。此外,您似乎在全局范围内进行计算,由于额外的类型不确定性,Julia的编译器无法执行许多有意义的优化。

        3
  •  3
  •   Community CDub    7 年前

    Python在控制流使用异常是好是坏这一问题上奇怪地模棱两可。看见 Python using exceptions for control flow considered bad? 。但即使在Python中,人们也一致认为用户代码不应该对控制流使用异常(尽管出于某些原因允许生成器这样做)。因此,基本上,简单的答案是,您不应该将异常用于特殊情况,而不是用于控制流。这就是为什么人们几乎没有付出任何努力来让Julia的try/catch构造更快——你不应该一开始就那样使用它。当然,我们可能会在某个时候加快速度。

    也就是说,作为Julia标准库的设计者,我们有责任确保我们提供的API不会强迫您使用异常来控制流。在这种情况下,您需要一个函数,该函数允许您尝试将某个值解析为浮点值,并通过抛出异常而不是返回正常值来指示是否可能。我们没有提供这样的API,所以这最终是Julia标准库的一个缺点,因为它现在就存在。我打开了一个问题来讨论这个API设计问题: https://github.com/JuliaLang/julia/issues/5704 我们会看看结果如何。