In theory, you're right - even C compilers make decisions about what to optimize and how. But in practice, the variance in the performance of C compiler outputs to dynamic language VMs is enormous.
With C you might get a 2-3x difference in common cases, but in a JS engine if it decides incorrectly to stay in the interpreter, you've lost 100x. If it enters a vicious cycle of deopts, it can be even worse. If it does a long GC all of a sudden, you can lose 300ms in an unpredictable way.
Again though, in principle all this is solvable in dynamic VMs. We know that theoretically and based on logical arguments; it would be great to see it proven in practice, but it hasn't yet.
With C you might get a 2-3x difference in common cases, but in a JS engine if it decides incorrectly to stay in the interpreter, you've lost 100x. If it enters a vicious cycle of deopts, it can be even worse. If it does a long GC all of a sudden, you can lose 300ms in an unpredictable way.
Again though, in principle all this is solvable in dynamic VMs. We know that theoretically and based on logical arguments; it would be great to see it proven in practice, but it hasn't yet.