private boolean isMedianGainNegative(List<TuningJobExecutionParamSet> tuningJobExecutionParamSets) {
    int numFitnessForMedian = 6;
    Double[] fitnessArray = new Double[numFitnessForMedian];
    int entries = 0;

    if (tuningJobExecutionParamSets.size() < numFitnessForMedian) {
      return false;
    }
    for (TuningJobExecutionParamSet tuningJobExecutionParamSet : tuningJobExecutionParamSets) {
      JobSuggestedParamSet jobSuggestedParamSet = tuningJobExecutionParamSet.jobSuggestedParamSet;
      JobExecution jobExecution = tuningJobExecutionParamSet.jobExecution;
      if (jobExecution.executionState == JobExecution.ExecutionState.SUCCEEDED
          && jobSuggestedParamSet.paramSetState == ParamSetStatus.FITNESS_COMPUTED) {
        fitnessArray[entries] = jobSuggestedParamSet.fitness;
        entries += 1;
        if (entries == numFitnessForMedian) {
          break;
        }
      }
    }
    Arrays.sort(fitnessArray);
    double medianFitness;
    if (fitnessArray.length % 2 == 0) {
      medianFitness = (fitnessArray[fitnessArray.length / 2] + fitnessArray[fitnessArray.length / 2 - 1]) / 2;
    } else {
      medianFitness = fitnessArray[fitnessArray.length / 2];
    }

    JobDefinition jobDefinition = tuningJobExecutionParamSets.get(0).jobSuggestedParamSet.jobDefinition;
    TuningJobDefinition tuningJobDefinition = TuningJobDefinition.find.where().
        eq(TuningJobDefinition.TABLE.job + '.' + JobDefinition.TABLE.id, jobDefinition.id).findUnique();
    double baselineFitness =
        tuningJobDefinition.averageResourceUsage * FileUtils.ONE_GB / tuningJobDefinition.averageInputSizeInBytes;

    if (medianFitness > baselineFitness) {
      logger.info("Switching off tuning for job: " + jobDefinition.jobName + " Reason: unable to tune enough");
      return true;
    } else {
      return false;
    }
  }
Checks if the median gain (from tuning) during the last 6 executions is negative
Last 6 executions constitutes 2 iterations of PSO (given the swarm size is three). Negative average gains in
latest 2 algorithm iterations (after a fixed number of minimum iterations) imply that either the algorithm hasn't
converged or there isn't enough scope for tuning. In both the cases, switching tuning off is desired
@param tuningJobExecutionParamSets List of previous executions
@return true if the median gain is negative, else false
app/com/linkedin/drelephant/tuning/FitnessComputeUtil.java