为什么使用 System.out.printf() 而不是 System.out.println() 会导致超出时间限制?

huangapple go评论72阅读模式
英文:

Why using System.out.printf() instead of System.out.println() causes Time Limit Exceeded?

问题

最近我在解答一个关于codeforces的问题。在编写解决方案时,我不得不打印一个二维数组中的值,我使用了以下代码:

for (int p = 0; p < m; p++) {
    if (positions[edges[p][0]-1] < positions[edges[p][1]-1]) {
        System.out.printf("%d %d\n", edges[p][0], edges[p][1]);
    } else {
        System.out.printf("%d %d\n", edges[p][1], edges[p][0]);
    }
}

使用上述方法导致一个测试用例出现了超时。当我将上述代码替换为以下代码时,它正常工作了。

for (int p = 0; p < m; p++) {
    if (positions[edges[p][0]-1] < positions[edges[p][1]-1]) {
        System.out.println((edges[p][0]) + " " + (edges[p][1]));
    } else {
        System.out.println((edges[p][1]) + " " + (edges[p][0]));
    }
}

是什么原因导致了这个问题?

我用于复现的提交在这里

英文:

Recently I was solving a question on codeforces. On coding its solution at the end I had to print the values from a 2 dimensional array for which I used,

for (int p = 0; p &lt; m; p++) {
    if (positions[edges

[0]-1] &lt; positions[edges

[1]-1]) { System.out.printf(&quot;%d %d\n&quot;, edges

[0], edges

[1]); } else { System.out.printf(&quot;%d %d\n&quot;, edges

[1], edges

[0]); } }

Using the above approach caused a Time Limit Exceed on a test case. While I replaced the above code to the one like the following, it worked.

for (int p = 0; p &lt; m; p++) {
    if (positions[edges

[0]-1] &lt; positions[edges

[1]-1]) { System.out.println((edges

[0]) + &quot; &quot; + (edges

[1])); } else { System.out.println((edges

[1]) + &quot; &quot; + (edges

[0])); } }

What could have caused this?

My submission for reproducing here

答案1

得分: 5

我创建了一个简单的测试(当然这不是一个基准测试,但它可以简单地得出一些结论):

public static void main(String[] args) {
    long beforePrintln = System.nanoTime();
    int a = 1;
    int b = 2;
    for (int i = 0; i < 1000000; i++) {
        System.out.println(a + " string " + b);
    }
    long beforePrintf = System.nanoTime();
    for (int i = 0; i < 1000000; i++) {
        System.out.printf("%d string %d\n", a, b);
    }
    long after = System.nanoTime();
    System.out.println();
    System.out.println(beforePrintf - beforePrintln);
    System.out.println(after - beforePrintf);
}

结果如下(我运行了多次,结果总是几乎相同):

4796301400
9976818400

看起来使用 printf(带有字符串格式化)要比带有字符串连接的 println 慢2倍。我认为 printf 的速度较慢,是因为它在格式化输出方面比简单的 println 更加强大,后者只是打印给定的行。

英文:

I created a simple test (of course it's not a benchmark, but it can simply give some conclusions):

public static void main(String[] args) {
	long beforePrintln = System.nanoTime();
	int a = 1;
	int b = 2;
	for (int i = 0; i &lt; 1000000; i++) {
		System.out.println(a + &quot; string &quot; + b);
	}
	long beforePrintf = System.nanoTime();
	for (int i = 0; i &lt; 1000000; i++) {
		System.out.printf(&quot;%d string %d\n&quot;, a, b);
	}
	long after = System.nanoTime();
	System.out.println();
	System.out.println(beforePrintf - beforePrintln);
	System.out.println(after - beforePrintf);
}

and the results are (I run it multiple times and result are always almost the same):

4796301400
9976818400

It seems that printf (with string formating) is 2 times slower than println with string concatenation. I think printf is slower because it's much more powerfull in formatting output than simple println which just prints given line.

huangapple
  • 本文由 发表于 2020年7月27日 17:58:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/63112912.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定