绘制文本并非易事:基准测试控制台与图形渲染。
Drawing Text Isn't Simple: Benchmarking Console vs. Graphical Rendering

原始链接: https://cv.co.hu/csabi/drawing-text-performance-graphical-vs-console.html

## 从 Go 到 C#: 一个基于文本的文件管理器之旅 为了学习 Go,作者开始了一个具有挑战性的项目:重写 FAR Manager,一个高效的基于文本的文件管理器。最初在 Go 中的尝试在寻求高性能屏幕输出时遇到了瓶颈,发现该语言不适合低级图形任务。转向 C# 和 .NET 开启了 GPU 加速渲染的大门。 对 GDI、DirectX 和 Vulkan 进行广泛测试后发现,DirectX 提供了最佳性能,但真正的瓶颈并非渲染 API 本身——而是 Windows 的 CPU 密集型字体绘制。一种将字符缓存为纹理的巧妙解决方案最初显示出希望,但最终证明对于典型用例来说,比优化的直接文本绘制更慢。 最终结论:**DirectX 结合直接文本绘制提供了速度和灵活性的最佳平衡。** 该项目强调了选择合适工具的重要性,打破了常见的性能假设,并强调了实现看似简单的任务(如在屏幕上显示文本)所需的知识深度。

黑客新闻 新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 绘制文本并非易事:控制台渲染与图形渲染基准测试 (co.hu) 4点 由 todsacerdoti 2小时前 | 隐藏 | 过去 | 收藏 | 讨论 考虑申请YC冬季2026批次!申请截止至11月10日 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文

So, this all started because I decided to learn Go. Polyglots say the best way to learn one is by doing something fun with it. Some watch movies, some read, some play with flashcards, others just jump into deep water and start talking with zero vocabulary.

I figured that logic should work for programming languages too - so I picked a fun target project: writing a text-based file manager. Think old-school Norton Commander or Dos Navigator. My personal favorite is still FAR Manager - it's insanely productive, still actively developed, and honestly the main reason I haven't switched to Linux or macOS yet.

Anyway, FAR Manager's code is in a language I don't speak, and writing plugins wouldn't get me where I want, so... I decided to just rewrite the whole thing. Easy, right? I know it's ridiculous, but that's fine - I like big impossible projects. Aim for the Moon, etc.

The Plan

I won't spoil the full idea (still might build it), but I disclose these two main modules:

  1. Input handling (keyboard, mouse)
  2. Output handling (drawing text on screen)

Let's skip the boring input stuff - it works, after wrestling with all the quirks of Windows' console mode. Long story short: the “modern” VT (Virtual Terminal) mode that Windows adopted from Linux is slower output and dumber input than the old API. It doesn't even tell you when Shift is pressed, only when you actually type an uppercase letter with it. Add in a few more edge cases like Ctrl+Alt+Shift chaos, and you get the idea. I found workarounds, though, so keyboard input is mostly done.

Now, the fun part.

Output: Drawing Text

How hard can it be to draw letters on a screen, right?

There are several ways to do it in the Windows console:

  • Old wayWriteConsoleOutputW - directly dump characters and color data to the screen.
  • New wayWriteConsoleW - embed color codes in the text (the VT way), richer (e.g. bold, italic, underline)

The new one is half as fast. On a modern mid-range PC, that's just sad.

So I looked for better options - maybe GPU acceleration? Some people pointed me to GPU-powered terminals with buttery-smooth rendering. Sounded good, so I dug deeper.

After days of poking Go, forums, and LLMs, it became clear that Go is not made for things like this. So I switched to something battle-tested: C#. (And if anyone tells you "every language can do anything", please slap them with a large trout. I mean, sure - but at what cost?)

C# means .NET, which can power full-blown 3D games, so drawing text should be child's play! I tried three rendering paths:

  1. GDI - the classic Windows graphics interface. Works even "without" a GPU, so obviously not fast.
  2. DirectX - the big guns, made for real-time 3D games.
  3. Vulkan - similar to DirectX but cross-platform.

I built a simple benchmark using all three plus the two console methods. The screen was 240x63 characters (Full HD with a 8x16 font). Test conditions were intentionally rough - every character with random colors - just to stress the system.

Results (random colors everywhere)

Renderer 240x63 80x25
WriteConsoleOutputW 20.3 64.5
WriteConsoleW 12.9 64.5
GDI 22.2 64.5
Vulkan 23.5 175.2
DirectX 17.6 130.5

All of them sucked, basically. Even with optimizations. But I measured the "optimistic" ways as well.

Results (realistic: white on black)

Renderer 240x63 80x25
WriteConsoleOutputW 64.5 64.5
WriteConsoleW 64.5 64.5
GDI 62.4 64.5
Vulkan 114.4 733.0
DirectX 140.2 944.5

Now we're talking. GPU rendering finally pays off - DirectX crushed it.

A Different Angle

Turns out the real bottleneck isn't the rendering API - it's Windows' font drawing (which is sadly CPU-bound). So I tried something unconventional: draw each character once, cache it as a texture, and then just copy those textures around. Copying pixels is much faster than redrawing fonts every frame.

That alone gave a massive speed bump in stress test (random colors):

Resolution DirectX + Texture
240x63 66.4
80x25 450.1

Nice jump - but there's a catch.

The Catch

Texturing looks great on paper, but you lose flexibility. You can't really optimize texture copies much more. On the other hand, writing text directly can be heavily optimized - for example, drawing an entire line at once when color and style match. That gives 5-7x speedups in practice.

Resolution DX + text DX + texture Change
240x63 17.6 66.4 +377% (stress test)
80x25 130.5 450.1 +345% (stress test)
240x63 140.2 66.4 -47% (normal use)
80x25 944.5 450.1 -47% (normal use)

So - caching helps in extreme cases, but slows things down in normal ones.

Conclusion

The sweet spot is DirectX + direct text drawing. It's fast enough, flexible, and still keeps the door open for fancier options like Vulkan if I ever go cross-platform.

Moral of the story: Drawing text on screen isn't simple, most of the internet forums got the bottleneck wrong, only a selected few know what's really happening under the hood.

联系我们 contact @ memedata.com