Andrei:
> I'm sure there are ways to further improve this, but there are a few
> difficulties. Each pass through the loop the code must transport values from
> the two arrays into a specific format and then distribute them for further
> calculation. Then, upon each popFront two words must be touched because
> arrays hold pointer+length, not pointer+pointer (as probably would be better
> since ranges are around).<
HOFs as zip/map/filter aren't D built-ins as in Python, but they are basic
language constructs. If the D front-end becomes a bit aware of what a zip is,
it probably becomes able to optimize away most or all those data movements.
The performance difference between the #3, #4, #5 and #5b (without zip
constructor) shows there's more space for improvements, optimization-wise.
In the Haskell Prelude (a standard module imported and compiled before any user
code) shows the implementation of zip(l1,l2) and zip3(l1,l2,l3):
zip :: [a] -> [b] -> [(a,b)]
zip = zipWith (,)
zip3 :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3 = zipWith3 (,,)
zipWith :: (a->b->c) -> [a]->[b]->[c]
zipWith z (a:as) (b:bs)
= z a b : zipWith z as bs
zipWith _ _ _ = []
zipWith3 :: (a->b->c->d) -> [a]->[b]->[c]->[d]
zipWith3 z (a:as) (b:bs) (c:cs)
= z a b c : zipWith3 z as bs cs
zipWith3 _ _ _ _ = []
They are tiny compared to Phobos code. They are efficient enough, and they have
no corner cases.
----------------------
spir:
>is clay's zip func lazy.<
It seems lazy, it's not an array of records, and the printing function refuses
to print it.
Bye,
bearophile