TakWolf / ark-pixel-font

Open source Pan-CJK pixel font / 开源的泛中日韩像素字体
http://ark-pixel-font.takwolf.com/
MIT License
3.27k stars 65 forks source link

构建字体的速度*非常慢* #34

Open pluiedev opened 5 months ago

pluiedev commented 5 months ago

之前在nixpkgs测试搭建方舟字体的时候,发现搭建全套字体居然花了15分钟多…… 慢得有一点不可理喻了。

...
python3.12-ark-pixel-font> INFO:font_service:Make font file: '/build/source/build/outputs/ark-pixel-16px-proportional-ko.pcf'
python3.12-ark-pixel-font> INFO:font_service:Make font collection file: '/build/source/build/outputs/ark-pixel-16px-proportional.otc'
python3.12-ark-pixel-font> INFO:font_service:Make font collection file: '/build/source/build/outputs/ark-pixel-16px-proportional.ttc'
python3.12-ark-pixel-font> buildPhase completed in 15 minutes 24 seconds

而且整个过程中CPU利用率没有超过10%(貌似是在单线程运转),完全没有达到用户硬件能够达到的速度。 目前肉眼能观察到,12px的字体比10px和16px搭建起来要慢很多,有没有可能搭建速度和字体中有的字符数量成正比?

pluiedev commented 5 months ago

好像已经有人在解决这个问题了呢(笑

31

TakWolf commented 5 months ago

目前 10px 和 16px 只有西文字母

仅 12px 包含汉字,因此构建速度很慢。

在单线程模式下,已经很难优化构建速度。但是 python 多线程改造非常丑陋

考虑在多个命令行按需执行:

python -m scripts.tasks.release_10px_monospaced
python -m scripts.tasks.release_12px_monospaced
python -m scripts.tasks.release_16px_monospaced
python -m scripts.tasks.release_10px_proportional
python -m scripts.tasks.release_12px_proportional
python -m scripts.tasks.release_16px_proportional

输出分别位于 outputs/release-*

参考:https://github.com/TakWolf/ark-pixel-font/tree/develop/.github/workflows

pluiedev commented 5 months ago

非常丑陋但还是得有呀…… Nix至少自己还有一些并行化的方法,但对于像AUR这种估计就很难受了

TakWolf commented 5 months ago

我对 Nix 和 Aur 不太了解,两者必须通过源代码构建吗?

是否允许直接下载构建产物(通过文件hash校验),类似于 homebrew 的模式?

https://github.com/Homebrew/homebrew-cask/blob/master/Casks/font/font-a/font-ark-pixel-12px-proportional.rb

因为这只是个字体,并不是程序或者类库,通过源代码构建并不能带来额外的收益。

TakWolf commented 5 months ago

关联问题:https://github.com/NixOS/nixpkgs/pull/313748

pluiedev commented 5 months ago

我对 Nix 和 Aur 不太了解,两者必须通过源代码构建吗?

是否允许直接下载构建产物(通过文件hash校验),类似于 homebrew 的模式?

Homebrew/homebrew-cask@master/Casks/font/font-a/font-ark-pixel-12px-proportional.rb

因为这只是个字体,并不是程序或者类库,通过源代码构建并不能带来额外的收益。

原则上都是最好源代码构建,因为Nix的一大核心就在于构建可重复性,尽量让Nix自己的构建系统把所有东西从源代码编译出来,而不是依赖于上端提供的下载包 (而且很多时候上端搭建过程中的bug也是靠给Nix重新写编译脚本找出来的

TakWolf commented 5 months ago

请教一下

我在 NixOS 中执行以下命令无法安装 ark-pixel-font

nix-shell -p ark-pixel-font

image image

我看到目前包被标记为 unstable,和此有关系吗? https://search.nixos.org/packages?channel=unstable&show=ark-pixel-font&from=0&size=50&sort=relevance&type=packages&query=ark-pixel-font

pluiedev commented 5 months ago

请教一下

我在 NixOS 中执行以下命令无法安装 ark-pixel-font


nix-shell -p ark-pixel-font

image

image

我看到目前包被标记为 unstable,和此有关系吗?

https://search.nixos.org/packages?channel=unstable&show=ark-pixel-font&from=0&size=50&sort=relevance&type=packages&query=ark-pixel-font

现在23.11作为稳定版本确实还没有这个包,得要么升级到unstable或者等到5月31号之后升级到24.05

你现在要试的话可以运行下nix run github:NixOS/nixpkgs/nixos-unstable#ark-pixel-font --experimental-features 'nix-command flakes'

TakWolf commented 5 months ago

再次尝试了并行构建改造,但是最终决定不支持并行构建。下面将简单阐述一下原因。

为什么现在的 build.py 构建非常慢?

单独构建一个字体速度并不慢。但是方舟事实上构建了非常多的字体。

目前一个完整的构建包括:3 个尺寸 2 种宽度模式(等宽和比例) 7 种地区字形版本 * 7 种字体格式 = 294 个字体。这还不包括其他构建物料。

即使构建一个字体需要 10 秒,总体算下来也需要将近 50 分钟。(实际上并没有这么长,目前只有 12px 有大量汉字字形,10px 和 16px 仅有西文字母,构建很快)

https://github.com/TakWolf/fusion-pixel-font 则是一个更极端的例子,三个尺寸除了有完整的汉字字形外,额外还有字体 dump ,字形合并等其他任务。实际完整构建时间超过 1 个小时。

目前在库文件以及构建脚本中,已经做了大量缓存优化,构建速度相比未优化已经提升了大约 1/3 左右。目前已经很难再继续优化。

但是方舟仍然计划继续添加其他字体格式的支持,所以未来构建时间仍可能不断增加。

为什么不支持并行构建

由于 Python 总所周知的 GIL 的问题,多线程只能实现并发,而非并行。如果想确实利用多核进行并行计算,需要使用多进程。

但是多进程会引入内存共享的问题,会大量增加脚本复杂度,目前不能接受。

构建脚本中已经包含了大量字体构建相关逻辑,已经相当复杂了,不希望继续增加额外的维护难度。

如何解决?

事实上,除了发布版本之外,大多数时间并不需要进行完整构建。

开发过程中,实际上只按需构建了 woff2 来生成预览 demo 进行调试。发布版本是,则使用了 6 个 github flow 任务来拆分构建。

而且,对于 X 系统而言,也并不需要完成构建,只需要一个轮廓字体(推荐 otf)以及一个位图字体(推荐 pcf),其他格式都是可替换格式。这个仅需要构建 14 个字体即可,耗时完全可以接受。

TakWolf commented 5 months ago

接下来计划将提供一个 build-cli.py 来支持按需构建以及日志级别支持,来满足包管理器基于源码构建的需要。