add test, and optimizing