You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中最快的终端文本打印函数是什么?还有更快方法吗?

控制台3D应用的高效文本打印优化方案

我正在开发一款控制台3D旋转立方体应用,需要实现最快的控制台文本打印。我用Very Sleepy性能分析器测试了几种方法的耗时(循环5000次打印全屏字符):

  • printf:192.2s
  • std::print:0.2s
  • std::cout:0.2s
  • WriteConsoleOutputA:1.1s

目前std::cout和std::print表现最优,但想知道有没有其他能接收控制台尺寸字符数组的更快打印方法。


优化现有方法的空间

首先可以对当前的std::cout和std::print代码做针对性优化,进一步压缩耗时:

  1. 关闭std::cout与C标准库的同步
    默认情况下std::cout会和stdio保持同步,关闭该特性可大幅减少底层开销:
#include <windows.h>
#include <iostream>

int main() {
    // 核心优化:关闭同步并解除cin与cout的绑定
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int i;
    HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO screen;
    GetConsoleScreenBufferInfo(console, &screen);
    short columns = screen.srWindow.Right - screen.srWindow.Left + 1;
    short rows = screen.srWindow.Bottom - screen.srWindow.Top + 1;
    char characters[columns * rows + 1];
    for (i = 0; i < columns * rows; i++) {
        characters[i] = '.';
    }
    characters[columns * rows] = '\0';
    for (i = 0; i < 5000; i++) {
        std::cout << characters;
        SetConsoleCursorPosition(console, (COORD){0, 0});
    }
    return 0;
}
  1. 避免std::print的重复字符串构造
    原代码中每次循环都构造std::string(characters),将字符串预构造在循环外,可消除重复的内存分配与拷贝开销:
#include <windows.h>
#include <print>
#include <string>

int main() {
    int i;
    HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO screen;
    GetConsoleScreenBufferInfo(console, &screen);
    short columns = screen.srWindow.Right - screen.srWindow.Left + 1;
    short rows = screen.srWindow.Bottom - screen.srWindow.Top + 1;
    char characters[columns * rows + 1];
    for (i = 0; i < columns * rows; i++) {
        characters[i] = '.';
    }
    characters[columns * rows] = '\0';
    // 预构造输出字符串,循环内复用
    std::string output_str(characters);
    for (i = 0; i < 5000; i++) {
        std::print("{}", output_str);
        SetConsoleCursorPosition(console, (COORD){0, 0});
    }
    return 0;
}

未提及的高效方法:直接调用WriteConsoleA

WriteConsoleA是Windows原生API,直接向控制台输出缓冲区写入字符,跳过C++标准库的中间封装,处理大字符数组时效率更优,且可直接接收char数组:

#include <windows.h>

int main() {
    int i;
    HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO screen;
    GetConsoleScreenBufferInfo(console, &screen);
    short columns = screen.srWindow.Right - screen.srWindow.Left + 1;
    short rows = screen.srWindow.Bottom - screen.srWindow.Top + 1;
    char characters[columns * rows + 1];
    for (i = 0; i < columns * rows; i++) {
        characters[i] = '.';
    }
    characters[columns * rows] = '\0';
    DWORD bytes_written;
    for (i = 0; i < 5000; i++) {
        WriteConsoleA(console, characters, columns * rows, &bytes_written, nullptr);
        SetConsoleCursorPosition(console, (COORD){0, 0});
    }
    return 0;
}

该方法直接与控制台内核交互,无标准库的额外开销,对于固定尺寸的全屏输出,速度会优于优化后的std::cout/std::print。

极限优化:锁定控制台缓冲区

若追求极致性能,可锁定控制台屏幕缓冲区内存,直接修改缓冲区内容后一次性写入,减少API调用的重复开销:

#include <windows.h>
#include <cstdlib>

int main() {
    int i;
    HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO screen;
    GetConsoleScreenBufferInfo(console, &screen);
    short columns = screen.srWindow.Right - screen.srWindow.Left + 1;
    short rows = screen.srWindow.Bottom - screen.srWindow.Top + 1;
    
    // 分配缓冲区内存
    COORD buffer_size = {columns, rows};
    CHAR_INFO* buffer = static_cast<CHAR_INFO*>(malloc(sizeof(CHAR_INFO) * columns * rows));
    if (!buffer) return 1;

    // 初始化缓冲区内容
    for (i = 0; i < columns * rows; i++) {
        buffer[i].Char.AsciiChar = '.';
        buffer[i].Attributes = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
    }

    // 修正写入区域:SMALL_RECT右边界为columns-1,避免越界
    SMALL_RECT write_area = {0, 0, static_cast<short>(columns - 1), static_cast<short>(rows - 1)};
    for (i = 0; i < 5000; i++) {
        // 若需实时更新画面,在此修改buffer内容即可
        WriteConsoleOutputA(console, buffer, buffer_size, {0, 0}, &write_area);
    }

    free(buffer);
    return 0;
}

此方法在频繁更新全屏内容时,仅需修改内存中的缓冲区,再一次性写入控制台,大幅降低了API调用的额外消耗,性能优于普通WriteConsoleOutputA调用。


内容的提问来源于stack exchange,提问作者Big

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 22:04:53