尝试捕获或在朱莉娅中键入转换性能 - (Julia 73秒,Python 0.5秒)

cha*_*ase 3 performance try-catch type-conversion julia

我一直在和朱莉娅一起玩,因为它似乎在语法上类似于python(我喜欢),但声称速度更快.但是,我尝试使用python中的类似脚本来测试数值在使用此函数的文本文件中的位置:

function isFloat(s)
    try:
        float64(s)
        return true
    catch:
        return false
    end
end
Run Code Online (Sandbox Code Playgroud)

出于某种原因,对于具有合理数量的文本行(~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
Run Code Online (Sandbox Code Playgroud)

朱莉娅:~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())
Run Code Online (Sandbox Code Playgroud)

Ste*_*son 7

另请注意,您可以使用标准库中的float64_isvalid函数来(a)检查字符串是否为有效的浮点值,以及(b)返回值.

另请注意,Julia 中的代码:后面try和代码中的冒号()是错误的(这是Python主义). catchisFloat

更快的代码版本应该是:

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"))
Run Code Online (Sandbox Code Playgroud)

在我的机器上,对于包含100,000行和10列数据的示例文件,其中50%是有效数字,您的Python代码需要4.21秒,而我的Julia代码需要2.45秒.


Joh*_*ite 5

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