Why does it not seem efficient enough? Creating them beforehand is certainly the optimal way to do it.
You can assign the color or texture of a material at runtime, but I don't think there is any support for creating new materials.. At least, that I know of.