some optimizations, added run loop