more memory efficient implementation