Optimisations taken from Fabiens Senglard's blog