import time import numpy as np import pylab n = [] t = [] f=4 rs=np.random.rand(50) while f < 1000000: i=int(f) val = set(np.random.rand(i)) t0 = time.clock() ou1= [j in val for j in rs] t1 = time.clock() n.append(len(val)) t.append(t1-t0) print n[-1], t[-1] f*=1.2 pylab.plot(n,t);pylab.show()
python 2.75 winxp32
4 3.54635463546e-05
4 3.47914791479e-05
5 3.41404140414e-05
6 3.3303330333e-05
8 3.29192919292e-05
7054 3.87518751875e-05
8465 3.71497149715e-05
10159 4.30603060306e-05
12190 4.29252925293e-05
14629 4.05670567057e-05
17554 4.01740174017e-05
324561 8.08100810081e-05
389474 8.11731173118e-05
467368 7.93249324933e-05
560842 8.10831083102e-05
673011 8.52385238526e-05
Моя художественная интерпретация:
Алгоритм с константным временем поиска. Но на больших объемах начинает сказываться выпадание из кэша.
Возвращаясь к теме
Что лучше
switch(i) { case 1:{f1(); break} case 20:{f20(); break} ..... }
или
set<int,void *f()> arr; arr[i]()
Рассмотрение получившихся ассемблерных кодов показало, что большинство компиляторов сваливается на банальный последовательный перебор i==1,i==20,… с джампами на соответствующий кусок кода. Иногда встречается двоичный поиск. Выравнивания блоков кода и вычисления адреса перехода ни разу не встретил :(