try catch or type conversion performance in julia - (Julia 73 seconds, Python 0.5 seconds)
我一直在和Julia玩,因为它在语法上类似于python(我喜欢它),但声称速度更快。但是,我尝试用类似于python中的脚本来测试使用此函数的文本文件中的数值:
1 2 3 4 5 6 7 8 | function isFloat(s) try: float64(s) return true catch: return false end end |
出于某种原因,这需要大量的时间来创建一个文本文件,其中包含相当数量的文本行(~500000)。为什么会这样?有更好的方法吗?从这一点上,我可以理解该语言的什么一般特征来应用于其他语言?
以下是我用时间运行的两个精确脚本供参考:
Python:~0.5秒
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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(' ').replace(',',' ').split(), file_data) bools = [(all(map(is_number, x)), x) for x in file_data] print time.time() - start |
茱莉亚:~73.5秒
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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()) |
还要注意,您可以使用标准库中的float64-is valid函数来(a)检查字符串是否是有效的浮点值,(b)返回该值。
还要注意,在你的
更快的代码版本应该是:
1 2 3 4 5 6 7 8 9 | 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秒。
这是一个有趣的性能问题,可能值得提交给Julia用户以获得比可能提供的更集中的反馈。乍一看,我认为您遇到了一些问题,因为(1)开始时Try/Catch的速度稍慢,然后(2)您使用Try/Catch的环境中存在大量类型不确定性,因为许多函数调用不返回稳定的类型。结果,Julia解释器花费大量的时间试图找出对象的类型,而不是进行计算。很难确切地知道大瓶颈在哪里,因为你做了很多在朱莉娅身上不太习惯的事情。而且,您似乎是在全局范围内进行计算,由于额外的类型不确定性,Julia的编译器无法执行许多有意义的优化。
在控制流中使用异常是好是坏这一问题上,python有点模棱两可。看到python使用异常处理被认为是坏的控制流吗?但是,即使在Python中,一致认为用户代码也不应该使用控制流的异常(尽管出于某种原因,允许生成器这样做)。因此,基本上,简单的答案是您不应该这样做——异常情况是针对异常情况的,而不是针对控制流的。这就是为什么茱莉亚的Try/Catch构造速度几乎为零的原因——首先,你不应该像那样使用它。当然,我们可能会在某个时候加快速度。
也就是说,作为Julia标准库的设计者,我们有责任确保我们提供的API不会强迫您使用控制流的异常。在这种情况下,您需要一个函数,它允许您尝试将某个内容解析为浮点值,并指示这是否可能––不是通过引发异常,而是通过返回正常值。我们不提供这样的API,所以这最终是Julia标准库的一个缺陷——正如它现在存在的那样。我打开了一个讨论这个API设计问题的问题:https://github.com/julialang/julian/issues/5704。我们来看看结果如何。