Does performance impact occur when using Guava.Preconditions with concatenated strings?

In our code, we often check the arguments with Preconditions:

Preconditions.checkArgument(expression, "1" + var + "3");

But sometimes this code is called very often. Could this have a noticeable negative effect on performance? If we move on to

Preconditions.checkArgument(expression, "%s%s%s", 1, var, 3);

?

(I expect the condition to be true most of the time. False means an error.)

+4
source share
3 answers

, - , . , ( .concat StringBuilder), , , , .

, , .

, Guava , %s. , {} ( slf4j log4j 2). , , , .

, , :

Preconditions.checkArgument(expression, "1%s3", var);

%s, , .

+5

String literal, , . , JDK , ( ).

, . Java StringBuilder, , , String.

, , . , , , , , , .

, : , . , .

+1

I wrote a simple test. Using formatting is much faster, as suggested here. The difference in performance increases with the number of calls (formatting performance does not change O (1)). I think the collection time of the garbage collector grows with the number of calls when using simple strings.

Here is one sample result:
started with 10000000 calls and  100 runs
formatter: 0.94 (mean per run)
string: 181.11 (mean per run)
Formatter is 192.67021 times faster. (this difference grows with number of calls)

Here is the code (Java 8, Guava 18):

import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import com.google.common.base.Preconditions;
import com.google.common.base.Stopwatch;

public class App {

    public static void main(String[] args) {
        int count = 10000000;
        int runs = 100;
        System.out.println("started with " + count + " calls and  " + runs + "runs");
        Stopwatch stopwatch = Stopwatch.createStarted();
        run(count, runs, i->fast(i));
        stopwatch.stop();
        float fastTime = (float)stopwatch.elapsed(TimeUnit.MILLISECONDS)/ runs;
        System.out.println("fast: " + fastTime + " (mean per run)");
        //
        stopwatch.reset();
        System.out.println("reseted: "+stopwatch.elapsed(TimeUnit.MILLISECONDS));
        stopwatch.start();
        run(count, runs,  i->slow(i));
        stopwatch.stop();
        float slowTime = (float)stopwatch.elapsed(TimeUnit.MILLISECONDS)/ runs;
        System.out.println("slow: " + slowTime + " (mean per run)");
        float times = slowTime/fastTime;
        System.out.println("Formatter is " + times + " times faster." );
    }

    private static void run(int count, int runs, Consumer<Integer> function) {
        for(int c=0;c<count;c++){
            for(int r=0;r<runs;r++){
                function.accept(r);
            }
        }
    }

    private static void slow(int i) {
        Preconditions.checkArgument(true, "var was " + i);
    }

    private static void fast(int i) {
        Preconditions.checkArgument(true, "var was %s", i);
    }

}
0
source

Source: https://habr.com/ru/post/1611556/


All Articles