Hi, I understand how scan works with a diadyc function such as (+) or (*), and hence implemented my version of a exponential moving average like that :
fun_ema:{[lambda; liste];
({[lambda; x; y]; (lambda*y)+ (x*1-lambda)}[lambda]\) liste
}
In the book I am reading, their operation over 1million lines is almost 2.5 times faster with this structure:
expma1:{[lambda;vector]
/ lambda -- memory
/ vector -- data
{[x;y;z] (x*y)+z}\[ first vector; 1 - lambda; vector * lambda]
};
Can someone explain how it works ? Thank you very much
Your fun_ema performs *, +, *, - a total of count[b] times. The operations are all on atom type data.
expma1 performs *, + a total of count[b] times and -, * once. The single use of * is on vector type data.
q uses vector instructions for speed. These take advantage of CPU instructions to be more efficient
q)a:til 1000000
q)b: til 1000000
q)\ts a+b // + operates on vectors and is fast
1 8388800
q)\ts a+'b // Using ' to force + to loop through each pair of atoms is much slower
26 32777488
q)\ts {x+y}'[a;b] //Wrapping in an unnecessary lambda is slower again
62 32777792
Since 4.0, kdb further sped up large vector operations by adding Multithreaded primitives which will spread the vector operations across multiple threads when available.