在 idea 中执行与在命令行执行,速度怎么相差这么大

122 天前
 chaoschick
public class Main {
public static void main(String[] args) {
long startTime = System.nanoTime();
long startTime2 = System.currentTimeMillis();
for (int i = -1; ++i < 1000; ) {
String row = "Column 1: " + "1" + ", Column 2: " + "2" +
", Column 3: " + "3" + ", Column 3: " + "4";
System.out.println(row);
}
long endTime = System.nanoTime();
long endTime2 = System.currentTimeMillis();

long durationInMillis = (endTime - startTime) / 1_000_000;
long durationInMillis2 = (endTime2 - startTime2) / 1;
System.out.println("Time taken to output the result: " + durationInMillis + " milliseconds");
System.out.println("Time taken to output the result: " + durationInMillis2 + " milliseconds");
}
}


idea
点击运行

Time taken to output the result: 6 milliseconds
Time taken to output the result: 6 milliseconds


cmd 命令提示符
java Main.java

Time taken to output the result: 143 milliseconds
Time taken to output the result: 145 milliseconds
2716 次点击
所在节点    程序员
22 条回复
lucasj
122 天前
可能运行参数不一样。idea 运行加了一堆 jvm 参数
chaoschick
122 天前
@lucasj 我把控制台中的 最上面那一部分的命令完全 copy 后放到 bat 批处理脚本
然后运行
Time taken to output the result: 121 milliseconds
Time taken to output the result: 121 milliseconds
mightybruce
122 天前
在控制台运行包含 jit 编译吧, 这个时间这么长 只有编译才需要这么久。
FrankAdler
122 天前
你 hold 主进程不退出,看下 idea 实际执行的可能是编译后的
kneo
122 天前
命令行先编译再执行。
chendy
122 天前
因为一样是 System.out.println ,打印到不同的地方耗时不一样,至于为什么不一样我就解释不出来了(可以问问 ai ?)
我这里把 1000 改成 10000
idea 执行 82
命令行 1452
命令行重定向到文件 55
不打印到屏幕上还是更快
chaoschick
122 天前
@kneo 试了 编译后再执行

Time taken to output the result: 122 milliseconds
Time taken to output the result: 122 milliseconds
chaoschick
122 天前
编译 javac Main.java
运行 java Main
chaoschick
122 天前
@chendy 我也怀疑这个 idea 可能做了什么操作
我使用 c++ 写了一个一样逻辑的代码 然后 g++ main.cpp -O3 && a.exe 测试发现也需要 100ms 左右
所以我怀疑 idea 的控制台
chendy
122 天前
@chaoschick 参考这个 https://stackoverflow.com/questions/42405829/performance-using-stdout-screen-vs-regular-file

应该是 buffer 的问题,某些场景 buffer 更大,flush 更少,于是更快
chaoschick
122 天前
@chendy
#include <iostream>
#include <chrono>
#include <sstream>

int main() {
// Output the result
auto start_time = std::chrono::high_resolution_clock::now();
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
const size_t bufferSize = 1024 * 1024 * 100;
char *buffer = new char[bufferSize];
std::cout.rdbuf()->pubsetbuf(buffer, bufferSize);

std::ostringstream oss;
for (int i = -1; ++i < 1000; ) {
oss << "Column 1: 1, Column 2: 2, Column 3: 3, Column 4: 4\n";
}
std::cout << oss.str();
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end_time - start_time;
std::cout << "Time taken to output the result: " << elapsed.count() << " milliseconds\n";

delete[] buffer;

return 0;
}

编译 g++ main.cpp -O3
运行 a.exe

Time taken to output the result: 124.007 milliseconds

这是 c++ 写的代码 我已经将 buffer 调大了 但是还是维持在 100ms 左右
leconio
122 天前
idea 不是默认 jbr 吗,你本地啥运行时。
kneo
122 天前
你把 bat 全贴一下。
chaoschick
122 天前
@leconio 我下载了 jbr17
D:\cpp\demo4\jbrsdk-17.0.9-windows-x64-b1087.7\bin\java Main.java

Time taken to output the result: 124 milliseconds
Time taken to output the result: 124 milliseconds
chaoschick
122 天前
#include <iostream>
#include <chrono>
#include <sstream>

int main() {
// Output the result
auto start_time = std::chrono::high_resolution_clock::now();
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
const size_t bufferSize = 1024 * 1024 * 100;
char *buffer = new char[bufferSize];
std::cout.rdbuf()->pubsetbuf(buffer, bufferSize);

std::ostringstream oss;
for (int i = -1; ++i < 1000; ) {
oss << "Column 1: 1, Column 2: 2, Column 3: 3, Column 4: 4\n";
}
std::cout << oss.str();
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end_time - start_time;
std::cout << "Time taken to output the result: " << elapsed.count() << " milliseconds\n";

delete[] buffer;

return 0;
}
我把同样的代码 在 linux 跑了一遍

g++ main.cpp -O3
./a.out

Time taken to output the result: 11.9875 milliseconds
。。。
RecursiveG
122 天前
你重定向到文件试试
chaoschick
122 天前
@RecursiveG 很快 我已经试过了 重定向到文件 10ms 以内了
RecursiveG
122 天前
那就是终端的瓶颈了, 我记得 cmd.exe 很慢的,你换个终端再试试
orioleq
122 天前
@kneo 你这回的是啥…人家问的和打印的都是执行时间
seanzxx
122 天前
你大量的文字输出,是在测试终端的处理和渲染的性能。
IDEA 的结果输出,只需要输出程序的控制台输出,可以简单的处理成输出到一个 buffer 或者文件,再输出到窗口,速度快是自然的。
终端 (Terminal) 复杂得多,举个简单的例子,它需要处理键盘输入,你还可以用 Ctrl + C 终端程序运行。
IntelliJ 里面带有完整功能 Terminal 界面的就慢很多。

在我的 MacBook 上, 这个代码在相同的 JDK 中耗费的时间是 (我把代码的 for 循环从 1000 改成了 10000 ,不然看不出差距):

IDEA 的 run:
Time taken to output the result: 25 milliseconds
Time taken to output the result: 26 milliseconds

IDEA 的 terminal:
Time taken to output the result: 188 milliseconds
Time taken to output the result: 188 milliseconds

MacOS 原生的 Terminal:
Time taken to output the result: 32 milliseconds
Time taken to output the result: 33 milliseconds

kitty(一个第三方 terminal 程序,使用了 GPU 加速,一般认为比系统自带的终端快):
Time taken to output the result: 29 milliseconds
Time taken to output the result: 30 milliseconds

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1067425

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX