Cpmoptimize works at the bytecode level, it takes Python bytecode and then
dynamically recompile it in an optimized version. This is basically a JIT.
* There is no Nim bytecode, everything is statically compiled, so you can't
do the same
* However you can create a macro / term-rewriting template that would catch
certain slow expressions and change them to an optimized version.
* Or if you're feeling adventurous, you can implement a x86_64 JIT to rewrite
at the CPU opcode level.
My advice is to use libraries with efficient implementations from the start.
Efficient implementations for numerical algorithms usually comes from linear
algebra or number theory and you can't automate that, so either the library
implements it efficiently, or there is something like cpmoptimize that detects
the pattern and rewrite it for efficiency.
Side-note, in the past I was having fun trying to compute Fibonacci with signal
processing techniques ("[Direct Form II transpose
filter](http://radio.feld.cvut.cz/matlab/toolbox/dspblks/directformiitransposefilt.html)").
It's super fast.
% Matlab code
% Project Euler 2
% sum of even fibonacci number <4 000 000
% transform parenthesis and curly brace into functions (matlab use
% parenthesis for both input and indexing :/
paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};
iseven = @(x) ~logical(bitget(x,1)); %returns TRUE if number is even
% keep only even number in matrix A: A(iseven(A))
%Y = FILTER(B,A,X) filters the data in vector X with the
% filter described by vectors A and B to create the filtered
% data Y. The filter is a "Direct Form II Transposed"
% implementation of the standard difference equation:
%
% a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)
% - a(2)*y(n-1) - ... - a(na+1)*y(n-na)
fib = @(n)filter(1,[1,-1,-1],[1,zeros(1,n-1)]);
n=1;
while paren(fib(n),n)<4e6
n=n+1;
end;
A=fib(n-1); sum(A(iseven(A)))
Run