Here are two different solutions for finding "Number of subarrays having product less than K", one with runtime O(n) and the other O(n^2). However, the one with O(n^2) finished executing about 4x faster than the one with linear runtime complexity (1s vs 4s). Could someone explain why this is the case, please?
Solution 1 with O(n) runtime:
static long countProductsLessThanK(int[] numbers, int k)
{
    if (k <= 1) { return 0; }
    int prod = 1;
    int count = 0;
    for (int right = 0, left = 0; right < numbers.length; right++) {
        prod *= numbers[right];
        while (prod >= k)
            prod /= numbers[left++];
        count += (right-left)+1;
    }
    return count;
}
Solution 2 with O(n^2) runtime:
static long countProductsLessThanK(int[] numbers, int k) {
    long count = 0;
    for (int i = 0; i < numbers.length; i++) {
        int productSoFar = 1;
        for (int j = i; j < numbers.length; j++) {
            productSoFar *= numbers[j];
            if (productSoFar >= k)
                break;
            count++;
        }
    }
    return count;
}
Sample main program:
public static void main(String[] args) {
    int size = 300000000;
    int[] numbers = new int[size];
    int bound = 1000;
    int k = bound/2;
    for (int i = 0; i < size; i++)
        numbers[i] = (new Random().nextInt(bound)+2);
    long start = System.currentTimeMillis();
    System.out.println(countProductLessThanK(numbers, k));
    System.out.println("O(n) took " + ((System.currentTimeMillis() - start)/1000) + "s");
    start = System.currentTimeMillis();
    System.out.println(countMyWay(numbers, k));
    System.out.println("O(n^2) took " + ((System.currentTimeMillis() - start)/1000) + "s");
}
Edit1:
The array size I chose in my sample test program has 300,000,000 elements.
Edit2:
array size: 300000000:
O(n) took 4152ms
O(n^2) took 1486ms
array size: 100000000:
O(n) took 1505ms
O(n^2) took 480ms
array size: 10000:
O(n) took 2ms
O(n^2) took 0ms
 
     
    