a memory efficient version