optimised a lot, with pointers