Search code examples
javaalgorithmpitest

Pi Test mutation surviving when trying to reduce time complexity


I have an algorithm that checks which String in a given List of Strings matches the most with another given string, it goes as-

    String calcMostMatching(String mainStr, List<String> strings) {
        String mostMatching = null;
        if (strings.size() == 1) {
          // if size is 1, return the only present string.
            mostMatching = strings.get(0);
        } else {
            // This algorithm also works for size() == 1 but I don't                       
            // want to use it when size() == 1
            char[] charArrayOfMainStr = mainStr.toCharArray();
            for (String str : strings) {
                char[] charArrayOfStr = str.toCharArray();
                int min = Math.min(charArrayOfMainStr.length, charArrayOfStr.length)
                for (int i = 0; i < min; i++) {
                    int count = 0;
                    if (charArrayOfMainStr[i] == charArrayOfStr[i]) {
                        count++;
                    } else {
                        break;
                    }
                }
                // Now I store the value of count for 
               // each string but let us say a method like str.setCounter(count);
            }

            // Now I will iterate over the loop to check the mostMatchingString

            mostMatching = strings.get(0);
            for (int i = 1; i < strings.size(); i++) {
                if (mostMatching.getCounter() < strings.get(i).getCounter()) {
                    mostMatching = strings.get(i);
                }
            }

        }
        return mostMatching;
    }

Now pit test fails on-

if (strings.size() == 1) {
   mostMatching = strings.get(0);
} 

Saying replaced strings.size() == 1 with false but still all the test cases pass. Yes, all the test cases will pass but I want to reduce time complexity when the list has only one value.

If you are not aware of pit testing, can someone help me to modify this algorithm so it doesn't go inside the loop when size() == 1 other than what I have done.

Note- This is not the real code, I have reduced it to the smallest reproducible example, the actual code is something different and quite complex, it checks on various parameters, rather than just comparing getCounter() values.

How can I kill this mutation or will I have to ignore it.


Solution

  • As performance is not a property of code that is measured by unit testing, code that is present only to optimise performance will result in equivalent mutations that cannot be killed.

    As a temporary exercise, you could also have pitest run performance tests, but this would be difficult as they normally give a quantitive result, rather than a boolean pass/fail. It would also be exceedingly slow.

    As your optimisation is for when n is low, it would be especially difficult to measure an observable improvement. It may be there is no actual improvement here at all. Unless you performance measurements that justify its presence, the simplest approach would be to reduce the complexity of your code by removing the if statement.