英文:
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 < m; p++) {
    if (positions[edges[0]-1] < positions[edges
[1]-1]) {
        System.out.printf("%d %d\n", edges
[0], edges
[1]);
    } else {
        System.out.printf("%d %d\n", 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 < m; p++) {
    if (positions[edges[0]-1] < positions[edges
[1]-1]) {
        System.out.println((edges
[0]) + " " + (edges
[1]));
    } else {
        System.out.println((edges
[1]) + " " + (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 < 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);
}
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论