add .cache()
move some function out, maybe this reduce memory usage