与朱莉娅一起表演。循环布尔数据
Performance with Julia. Looping through boolean data
N = 100000
a = randbool(N)
b = randbool(N)
这是我当前的代码(我的代码中较慢的部分)
onefalse = a $ b
twofalses = !a & !b
sum(onefalse)
sum(twofalses)
有什么方法可以改进这段代码吗?我感觉我在 a
和 b
之间循环了两次。我尝试使用 for
循环和 if 语句,但速度较慢。
for i = 1:N
if a[i]
if b[i]
else
onefalse+=1
end
else
if b[i]
onefalse+=1
else
twofalses+=1
end
end
end
首先,一个有效的问题是为什么for循环版本很慢。部分原因是 randbool
给出了 BitArray
,而不是普通数组。出于好奇,我决定与 Array{Bool}
进行比较。我能够加快一点速度 - 我认为你可能已经达到了可能的极限。特别是,索引到 Array{Bool}
似乎比 BitArray
更快,但是像这里所做的那样对 BitArrays
的操作很难被击败。
function countfalse1(N, a, b)
return sum(a $ b), sum(!a & !b)
end
function countfalse2(N, a, b)
return N-sum(a), N-sum(a|b)
end
function countfalse3(N, a, b)
onef, twof = 0, 0
@inbounds for i = 1:N
if a[i]
if !b[i]
onef += 1
end
else
if b[i]
onef += 1
else
twof += 1
end
end
end
return onef, twof
end
srand(1000)
N = 10000000
a = randbool(N)
b = randbool(N)
c = Bool[a[i] for i in 1:N]
d = Bool[b[i] for i in 1:N]
println("BitArray")
@show countfalse1(N, a, b)
@time countfalse1(N, a, b)
@time countfalse1(N, a, b)
@time countfalse1(N, a, b)
@show countfalse2(N, a, b)
@time countfalse2(N, a, b)
@time countfalse2(N, a, b)
@time countfalse2(N, a, b)
@show countfalse3(N, a, b)
@time countfalse3(N, a, b)
@time countfalse3(N, a, b)
@time countfalse3(N, a, b)
println("\nArray{Bool}")
@show countfalse1(N, c, d)
@time countfalse1(N, c, d)
@time countfalse1(N, c, d)
@time countfalse1(N, c, d)
@show countfalse2(N, c, d)
@time countfalse2(N, c, d)
@time countfalse2(N, c, d)
@time countfalse2(N, c, d)
@show countfalse3(N, c, d)
@time countfalse3(N, c, d)
@time countfalse3(N, c, d)
@time countfalse3(N, c, d)
给予
BitArray
countfalse1(N,a,b) => (5001756,2500026)
elapsed time: 0.004565573 seconds (5014328 bytes allocated)
elapsed time: 0.003607561 seconds (5000528 bytes allocated)
elapsed time: 0.013880181 seconds (5000528 bytes allocated, 83.83% gc time)
countfalse2(N,a,b) => (5003620,2500026)
elapsed time: 0.000784883 seconds (1250240 bytes allocated)
elapsed time: 0.000752576 seconds (1250240 bytes allocated)
elapsed time: 0.000758695 seconds (1250240 bytes allocated)
countfalse3(N,a,b) => (5001812,2500026)
elapsed time: 0.120491323 seconds (144 bytes allocated)
elapsed time: 0.118401949 seconds (144 bytes allocated)
elapsed time: 0.11807728 seconds (144 bytes allocated)
Array{Bool}
countfalse1(N,c,d) => (5001756,2500026)
elapsed time: 0.098838752 seconds (40000640 bytes allocated)
elapsed time: 0.112468122 seconds (40000640 bytes allocated, 10.64% gc time)
elapsed time: 0.11305269 seconds (40000640 bytes allocated, 10.22% gc time)
countfalse2(N,c,d) => (5003620,2500026)
elapsed time: 0.066169587 seconds (10000328 bytes allocated)
elapsed time: 0.084794646 seconds (10000328 bytes allocated, 17.78% gc time)
elapsed time: 0.067458965 seconds (10000328 bytes allocated)
countfalse3(N,c,d) => (5001812,2500026)
elapsed time: 0.066095076 seconds (144 bytes allocated)
elapsed time: 0.067585543 seconds (144 bytes allocated)
elapsed time: 0.06718118 seconds (144 bytes allocated)
N = 100000
a = randbool(N)
b = randbool(N)
这是我当前的代码(我的代码中较慢的部分)
onefalse = a $ b
twofalses = !a & !b
sum(onefalse)
sum(twofalses)
有什么方法可以改进这段代码吗?我感觉我在 a
和 b
之间循环了两次。我尝试使用 for
循环和 if 语句,但速度较慢。
for i = 1:N
if a[i]
if b[i]
else
onefalse+=1
end
else
if b[i]
onefalse+=1
else
twofalses+=1
end
end
end
首先,一个有效的问题是为什么for循环版本很慢。部分原因是 randbool
给出了 BitArray
,而不是普通数组。出于好奇,我决定与 Array{Bool}
进行比较。我能够加快一点速度 - 我认为你可能已经达到了可能的极限。特别是,索引到 Array{Bool}
似乎比 BitArray
更快,但是像这里所做的那样对 BitArrays
的操作很难被击败。
function countfalse1(N, a, b)
return sum(a $ b), sum(!a & !b)
end
function countfalse2(N, a, b)
return N-sum(a), N-sum(a|b)
end
function countfalse3(N, a, b)
onef, twof = 0, 0
@inbounds for i = 1:N
if a[i]
if !b[i]
onef += 1
end
else
if b[i]
onef += 1
else
twof += 1
end
end
end
return onef, twof
end
srand(1000)
N = 10000000
a = randbool(N)
b = randbool(N)
c = Bool[a[i] for i in 1:N]
d = Bool[b[i] for i in 1:N]
println("BitArray")
@show countfalse1(N, a, b)
@time countfalse1(N, a, b)
@time countfalse1(N, a, b)
@time countfalse1(N, a, b)
@show countfalse2(N, a, b)
@time countfalse2(N, a, b)
@time countfalse2(N, a, b)
@time countfalse2(N, a, b)
@show countfalse3(N, a, b)
@time countfalse3(N, a, b)
@time countfalse3(N, a, b)
@time countfalse3(N, a, b)
println("\nArray{Bool}")
@show countfalse1(N, c, d)
@time countfalse1(N, c, d)
@time countfalse1(N, c, d)
@time countfalse1(N, c, d)
@show countfalse2(N, c, d)
@time countfalse2(N, c, d)
@time countfalse2(N, c, d)
@time countfalse2(N, c, d)
@show countfalse3(N, c, d)
@time countfalse3(N, c, d)
@time countfalse3(N, c, d)
@time countfalse3(N, c, d)
给予
BitArray
countfalse1(N,a,b) => (5001756,2500026)
elapsed time: 0.004565573 seconds (5014328 bytes allocated)
elapsed time: 0.003607561 seconds (5000528 bytes allocated)
elapsed time: 0.013880181 seconds (5000528 bytes allocated, 83.83% gc time)
countfalse2(N,a,b) => (5003620,2500026)
elapsed time: 0.000784883 seconds (1250240 bytes allocated)
elapsed time: 0.000752576 seconds (1250240 bytes allocated)
elapsed time: 0.000758695 seconds (1250240 bytes allocated)
countfalse3(N,a,b) => (5001812,2500026)
elapsed time: 0.120491323 seconds (144 bytes allocated)
elapsed time: 0.118401949 seconds (144 bytes allocated)
elapsed time: 0.11807728 seconds (144 bytes allocated)
Array{Bool}
countfalse1(N,c,d) => (5001756,2500026)
elapsed time: 0.098838752 seconds (40000640 bytes allocated)
elapsed time: 0.112468122 seconds (40000640 bytes allocated, 10.64% gc time)
elapsed time: 0.11305269 seconds (40000640 bytes allocated, 10.22% gc time)
countfalse2(N,c,d) => (5003620,2500026)
elapsed time: 0.066169587 seconds (10000328 bytes allocated)
elapsed time: 0.084794646 seconds (10000328 bytes allocated, 17.78% gc time)
elapsed time: 0.067458965 seconds (10000328 bytes allocated)
countfalse3(N,c,d) => (5001812,2500026)
elapsed time: 0.066095076 seconds (144 bytes allocated)
elapsed time: 0.067585543 seconds (144 bytes allocated)
elapsed time: 0.06718118 seconds (144 bytes allocated)