2015-02-21 4 views
1
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 
+4

В дополнении к отличному ответу IainDunning, он стоит выдавать напоминание: если вы заботитесь о производительности, всегда положить вещи внутри функций. См. Страницу рекомендаций по производительности руководства. – tholy

ответ

4

Прежде всего, правильный вопрос - почему медленная версия цикла. Отчасти потому, что 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)