V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
chaoschick
V2EX  ›  程序员

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

  •  
  •   chaoschick · 2024-08-24 10:40:31 +08:00 · 2965 次点击
    这是一个创建于 374 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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
    22 条回复    2024-08-26 07:40:28 +08:00
    lucasj
        1
    lucasj  
       2024-08-24 10:43:49 +08:00
    可能运行参数不一样。idea 运行加了一堆 jvm 参数
    chaoschick
        2
    chaoschick  
    OP
       2024-08-24 10:53:39 +08:00
    @lucasj 我把控制台中的 最上面那一部分的命令完全 copy 后放到 bat 批处理脚本
    然后运行
    Time taken to output the result: 121 milliseconds
    Time taken to output the result: 121 milliseconds
    mightybruce
        3
    mightybruce  
       2024-08-24 11:00:35 +08:00
    在控制台运行包含 jit 编译吧, 这个时间这么长 只有编译才需要这么久。
    FrankAdler
        4
    FrankAdler  
       2024-08-24 12:46:37 +08:00 via Android
    你 hold 主进程不退出,看下 idea 实际执行的可能是编译后的
    kneo
        5
    kneo  
       2024-08-24 13:07:39 +08:00 via Android
    命令行先编译再执行。
    chendy
        6
    chendy  
       2024-08-24 13:08:59 +08:00
    因为一样是 System.out.println ,打印到不同的地方耗时不一样,至于为什么不一样我就解释不出来了(可以问问 ai ?)
    我这里把 1000 改成 10000
    idea 执行 82
    命令行 1452
    命令行重定向到文件 55
    不打印到屏幕上还是更快
    chaoschick
        7
    chaoschick  
    OP
       2024-08-24 13:13:37 +08:00
    @kneo 试了 编译后再执行

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

    应该是 buffer 的问题,某些场景 buffer 更大,flush 更少,于是更快
    chaoschick
        11
    chaoschick  
    OP
       2024-08-24 13:58:53 +08:00
    @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
        12
    leconio  
       2024-08-24 14:23:41 +08:00 via iPhone
    idea 不是默认 jbr 吗,你本地啥运行时。
    kneo
        13
    kneo  
       2024-08-24 14:38:58 +08:00 via Android
    你把 bat 全贴一下。
    chaoschick
        14
    chaoschick  
    OP
       2024-08-24 14:40:02 +08:00
    @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
        15
    chaoschick  
    OP
       2024-08-24 15:20:31 +08:00
    #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
        16
    RecursiveG  
       2024-08-24 15:22:14 +08:00
    你重定向到文件试试
    chaoschick
        17
    chaoschick  
    OP
       2024-08-24 15:28:56 +08:00
    @RecursiveG 很快 我已经试过了 重定向到文件 10ms 以内了
    RecursiveG
        18
    RecursiveG  
       2024-08-24 15:31:14 +08:00
    那就是终端的瓶颈了, 我记得 cmd.exe 很慢的,你换个终端再试试
    orioleq
        19
    orioleq  
       2024-08-24 17:04:52 +08:00 via iPhone
    @kneo 你这回的是啥…人家问的和打印的都是执行时间
    seanzxx
        20
    seanzxx  
       2024-08-25 02:37:28 +08:00
    你大量的文字输出,是在测试终端的处理和渲染的性能。
    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
    chaoschick
        21
    chaoschick  
    OP
       2024-08-26 07:12:24 +08:00
    @seanzxx 那多半就是 windows 的终端有问题了 我试过 windows 的 cmd 与 powershell 都有这个问题
    chaoschick
        22
    chaoschick  
    OP
       2024-08-26 07:40:28 +08:00
    g++ main.cpp -O3
    a.exe

    windows 7 (vmware)
    Time taken to output the result: 122.007 milliseconds

    windows 10 (物理机)
    Time taken to output the result: 3.7429 milliseconds

    windows server 2019 (内网服务器)
    Time taken to output the result: 73.7804 milliseconds
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2580 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:25 · PVG 23:25 · LAX 08:25 · JFK 11:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.