package org.tbray.ongoing;

import java.io.*;
import java.util.*;

public class FastLoop
{
  int frob(int in)
  {
    return (in % 1234) & 0xff;
  }

  int sum1(int [] a)
  {
    int sum = 0;
    for (int i = 0; i < a.length; i++)
      sum += frob(a[i]);
    return sum;
  }

  int sum2(int [] a)
  {
    int sum = 0;
    int i = 0;
    try
    {
      while (true)
	sum += frob(a[i++]);
    }
    catch (ArrayIndexOutOfBoundsException e)
    {
      if (i >= a.length)
	return sum;
      throw e;
    }
  }

  public static void main( String args[] )
  {
    // now let's do some time trials
    Random r = new Random(666);

    int [] lengths = { 100, 1000, 10000, 100000, 1000000 };
    int [] m1 = new int[1000000];

    for (int i = 0; i < m1.length; i++)
      m1[i] = r.nextInt(111);

    long [] times1 = new long[lengths.length];
    long [] times2 = new long[lengths.length];
    for (int i = 0; i < times1.length; i++)
      times1[i] = times2[i] = 0;

    FastLoop me = new FastLoop();
    int last = me.sum1(m1);

    for (int i = 0; i < lengths.length; i++)
    {
      int m1I = 0;
      int times = 1000000 / lengths[i];
      int [] a = new int[lengths[i]];
      int sum = 0;
      for (int run = 0; run < times; run++)
      {
	for (int ai = 0; ai < a.length; ai++)
	  a[ai] = m1[m1I++];
	
	sum += me.capture(a, times1, times2, i);
      }
      if (sum != last)
	throw new RuntimeException("Bad sum, length "+lengths[i]);
    }

    for (int i = 0; i < times1.length; i++)
    {
      int times = 1000000 / lengths[i];
      double s1 = ((double) times1[i]) / 1000.0;
      double s2 = ((double) times2[i]) / 1000.0;
      System.out.println(times+"*"+lengths[i]+": "+s1+"/"+s2);
    }
  }

  int capture(int [] a, long [] t1, long [] t2, int tslot)
  {
    long before = System.currentTimeMillis();
    int s1 = sum1(a);
    long after = System.currentTimeMillis();
    t1[tslot] += after - before;
    before = after;
    int s2 = sum2(a);
    t2[tslot] += System.currentTimeMillis() - before;
    if (s1 != s2)
      throw new RuntimeException("Sums differ!");
    
    return s1;
  }
}

