Is the sieve an improvement for prime finding over an optimized algorithm?
Sorry, but you can’t just count loops, the number of loops is totally irrelevant. 

If you count nested loops, that is slightly significant but can be very misleading. 

You need to count how many iterations a loop performs. In the first example, the number of iterations is up to primes.length, which is around n / log n. In the second example, the number of iterations in the inner loop is less than n / 2i, and i grows quickly. 

Add a counter to each function and see how often the inner loop gets executed. 

PS. Let n = 1 billion, and print say every 100th prime added to primeVals. Then check how long it takes. The sieve will take a good time. But I can promise you, the “optimised” algorithm will be a lot more than ten times slower.