朱莉娅:基本功能比同类功能快10,000倍

时间:2015-07-02 03:27:41

标签: binary julia

我正在玩朱莉娅的十进制到二进制转换器'bin()',希望提高性能。我需要使用BigInts来解决这个问题,并在我的文件中使用bigInt调用bin()输出正确的二进制表示;但是,调用类似于bin()函数的函数会花费一分钟的时间,而bin()则需要大约0.003秒。为什么会有这么大的差异?

function binBase(x::Unsigned, pad::Int, neg::Bool)
    i = neg + max(pad,sizeof(x)<<3-leading_zeros(x))
    a = Array(Uint8,i)
    while i > neg
        a[i] = '0'+(x&0x1)
        x >>= 1
        i -= 1
    end
    if neg; a[1]='-'; end
    ASCIIString(a)
end



function bin1(x::BigInt, pad::Int)
    y = bin(x)
end



function bin2(x::BigInt, pad::Int,a::Array{Uint8,1}, neg::Bool)
    while pad > neg
        a[pad] = '0'+(x&0x1)
        x >>= 1
        pad -= 1
    end
    if neg; a[1]='-'; end
    ASCIIString(a)
end




function test()
    a = Array(Uint8,1000001)
    x::BigInt= 2
    x = (x^1000000)


    @time bin1(x,1000001)
    @time bin2(x,1000001,a,true)

end

test()

2 个答案:

答案 0 :(得分:5)

正如Felipe Lema所指出的,Base将BigInt打印到GMP,它可以打印BigInts而不用它们进行任何中间计算 - 用BigInts进行大量计算以找出它们的数字非常慢并最终分配大量内存。底线:对于像Int64这样的东西来说,做x >>= 1非常有效,但对BigInts这样的东西来说效率不高。

答案 1 :(得分:4)

使用julia's profiling tools我可以看到Base.bin正在调用来自libGMP的C函数,该函数具有各种特定于机器的优化(某处herempn_get_str is being called)。

@profile bin1(x,1000001)
Profile.print()
Profile.clear()
@profile bin2(x,1000001,a,true)
Profile.print()
Profile.clear() 

我还可以看到字节分配的巨大差异(bin1:1000106,bin2:62648125016),这需要更多的分析和调整,但我想前一段足以得到答案。