I had to report the mean running time of a java method. I do it the following way
//method start
long startTime = System.nanoTime();
//method body here ...
long estimationTime = System.nanoTime() - startTime; 
//method end
I run the method many many times, log the results and then report the mean and variance of running time in microseconds.
Here is the problem I got the following values (very large spikes exist)

note that other values are not zeros (zoom in reveals it)

My Questions:
- What the main cause of these outliers (spikes)?
- How to report the running time accurately in a case like this?
Take a look at the method body (For the curious)
TraceRecord resultRecord = new TraceRecord();
    resultRecord.setTimeStamp(timeStamp);
    resultRecord.setUserID(userID);
    if (sensorValue.getSensorType() == SensorType.WIFI) {
        ArrayList<WifiBaseStation> wifiAPsInRange = new ArrayList<WifiBaseStation>();
        for (int i = 0; i < sensorValue.getBaseStationsIdentifiers().length; i++) {
            WifiBaseStation wifiAP = new WifiBaseStation(sensorValue.getRepresentativeName(i),
                    sensorValue.getBaseStationsIdentifier(i));
            wifiAP.getSignalStrengthsList().add(sensorValue.getSignalValue(i));
            wifiAPsInRange.add(wifiAP);
        }
        if (wifiAPsInRange.size() > 0) {
            double averageLong = 0;
            double averageLat = 0;
            int matchedCount = 0;
            for (WifiBaseStation bs : wifiAPsInRange) {
                WifiBaseStation bsFromTable = WiFiUniqueWarDrivingTable.Get(bs.getMacAddress());
                if (bsFromTable != null) {
                    GPSLocation locationFromTable = bsFromTable.getBaseStationLocationUsingAverage();
                    if (locationFromTable != null) {
                        averageLong += locationFromTable.getLongitude();
                        averageLat += locationFromTable.getLatitude();
                        matchedCount++;
                    }else{
                        averageLong++;
                        averageLong--;
                    }
                }else{
                    averageLong++;
                    averageLong--;
                }
            }
            if (averageLong != 0) {
                averageLong /= matchedCount;
            }
            if (averageLat != 0) {
                averageLat /= matchedCount;
            }
            if (averageLat != 0 && averageLong != 0) {
                resultRecord.setLocationPoint(new GPSLocation(averageLong, averageLat, 0));
            } else {
                return null;
            }
        }
    }
 
     
     
     
     
    