二进制小型化优化

1 二进制小型化优化方案

适用范围:C / C++ / Rust / Go / Swift / Android / iOS / 嵌入式固件等场景


1.1 概述与基础概念

1.1.1 为什么要做二进制小型化?

场景 主要收益
移动端 App 降低用户下载门槛、减少卸载率、节省流量
嵌入式/IoT Flash/ROM 容量受限,直接决定能否运行
服务端微服务 加速容器镜像拉取、缩短冷启动时间
WebAssembly 减少网络传输、提升首屏加载速度
边缘计算 硬件算力/存储双受限

1.1.2 二进制的组成结构(ELF 为例)

复制代码
ELF Binary
├── .text          ← 可执行代码段(通常最大)
├── .rodata        ← 只读数据(字符串常量、查找表)
├── .data          ← 已初始化全局/静态变量
├── .bss           ← 未初始化全局/静态变量(不占文件体积)
├── .debug_*       ← 调试信息(DWARF)
├── .symtab        ← 符号表
├── .dynsym        ← 动态符号表
└── ...

1.1.3 衡量指标

  • 文件大小(File Size):磁盘/下载占用,用户感知最直接
  • 安装大小(Installed Size):解压/安装后的占用,iOS/Android 商店展示
  • 内存映像大小(VM Size):运行时进程占用,影响 OOM 风险
  • 下载大小(Download Size):经过 gzip/brotli 压缩后,实际网络传输量

1.2 编译器层面优化

1.2.1 优化等级选择

1.2.1.1 GCC / Clang
bash 复制代码
-O0   # 不优化(调试用)
-O1   # 基础优化,略微缩小代码
-O2   # 标准优化(速度优先)
-O3   # 激进优化(可能膨胀二进制)
-Os   # 针对尺寸优化(= O2 去掉会膨胀体积的 pass)
-Oz   # 比 Os 更激进的尺寸优化(Clang 独有,速度换体积)
-Og   # 调试友好优化

经验法则 :大多数尺寸敏感项目首选 -Os;若能接受性能下降,Clang -Oz 可额外节省 5%~15%。

1.2.1.2 MSVC(Windows)
复制代码
/O1   # 最小代码优化
/O2   # 最快速度(体积可能更大)
/Os   # 速度与大小之间倾向大小
/GL   # 全程序优化(配合 /LTCG 使用)
1.2.1.3 Rust
toml 复制代码
# Cargo.toml
[profile.release]
opt-level = "z"    # 最小体积("s" 次之)
lto = true
codegen-units = 1
panic = "abort"
strip = true

1.2.2 链接时优化(LTO / LTCG)

LTO 允许编译器跨编译单元进行分析,消除冗余代码。

bash 复制代码
# GCC Full LTO
gcc -flto -O2 -o output main.c utils.c

# Clang ThinLTO(并行,构建更快)
clang -flto=thin -O2 -o output main.c utils.c

# Rust
[profile.release]
lto = "thin"   # 或 lto = true(fat LTO,更慢更彻底)

⚠️ LTO 会显著增加链接时间和内存消耗,CI 机器需评估资源。

1.2.3 函数/数据节(Section)粒度控制

bash 复制代码
# GCC/Clang:每个函数/变量单独放入一个节,便于链接器裁剪
-ffunction-sections
-fdata-sections

配合链接器 --gc-sections 使用,可删除所有未引用的节。

1.2.4 Profile-Guided Optimization(PGO)

PGO 让编译器根据实际运行数据重排热路径,使 CPU 指令缓存命中更好,同时可将冷路径代码移至独立节,便于剔除。

bash 复制代码
# Step 1:插桩编译
clang -fprofile-instr-generate -o app_instrumented main.c

# Step 2:运行典型场景,收集 profraw
./app_instrumented
llvm-profdata merge -output=app.profdata *.profraw

# Step 3:使用 profile 重新编译
clang -fprofile-instr-use=app.profdata -O2 -o app main.c

1.2.5 其他编译选项

bash 复制代码
# 不生成异常处理表(若项目不使用 C++ 异常)
-fno-exceptions

# 不生成 RTTI(若不使用 dynamic_cast / typeid)
-fno-rtti

# 不展开循环(减少代码膨胀)
-fno-unroll-loops

# 内联函数阈值(减小可降低代码膨胀)
-finline-limit=10

# 禁用栈保护(嵌入式等安全不敏感场景)
-fno-stack-protector

# 使用短枚举(嵌入式)
-fshort-enums

# 合并重复常量字符串
-fmerge-all-constants

1.2.6 指令集选择

在嵌入式/ARM 场景中,指令集直接影响代码密度:

bash 复制代码
# ARM Thumb2 指令集(16/32 位混合,比 ARM 32 位更紧凑)
-mthumb

# RISC-V:使用压缩指令集扩展(RVC)
-march=rv32imc

1.3 链接器层面优化

1.3.1 Dead Code Elimination(DCE)

bash 复制代码
# GNU ld / gold
-Wl,--gc-sections

# macOS ld
-Wl,-dead_strip

# lld(LLVM)
-Wl,--gc-sections

必须配合编译器的 -ffunction-sections -fdata-sections 使用,否则无效。

1.3.2 选择高效链接器

链接器 特点
ld(GNU BFD) 最广泛,但慢,优化能力一般
gold 比 BFD 快,支持 LTO
lld(LLVM) 最快,LTO/ThinLTO 支持最好,推荐首选
mold 极速(并行链接),但尺寸优化功能与 lld 相当
bash 复制代码
# 切换到 lld
-fuse-ld=lld

1.3.3 版本脚本(Version Script)

控制导出的符号,隐藏不必要的符号可减小 .dynsym 表。

ld 复制代码
# version.map
{
  global:
    my_public_api;   # 仅导出这个
  local:
    *;               # 其余全部隐藏
};
bash 复制代码
gcc -Wl,--version-script=version.map -o libfoo.so foo.c

1.3.4 符号可见性

c 复制代码
// 方式1:GCC 属性
__attribute__((visibility("hidden"))) void internal_func() {}
__attribute__((visibility("default"))) void public_api() {}

// 方式2:编译器全局默认隐藏
// -fvisibility=hidden
// 再对需要导出的符号单独标记 default

1.3.5 ICF(Identical Code Folding)

将内容完全相同的函数合并为一个,可显著缩减模板/泛型代码膨胀。

bash 复制代码
# lld
-Wl,--icf=all

# gold
-Wl,--icf=safe

# MSVC
/OPT:ICF

⚠️ --icf=all 可能破坏以函数地址作为唯一标识的代码,使用前需测试。

1.3.6 去除 PLT(Procedure Linkage Table)

bash 复制代码
# 对于已知位置的符号,直接调用而非通过 PLT
-Wl,-z,now      # 启动时立即解析所有符号(RELRO)
-fno-plt        # 直接调用,跳过 PLT

1.4 代码层面优化

1.4.1 避免模板过度实例化(C++)

cpp 复制代码
// ❌ 每个 T 都生成一套代码
template<typename T>
void process(T* ptr, size_t n) { /* 大量逻辑 */ }

// ✅ 类型无关逻辑抽到非模板函数
void process_impl(void* ptr, size_t elem_size, size_t n);

template<typename T>
inline void process(T* ptr, size_t n) {
    process_impl(ptr, sizeof(T), n);   // 薄包装
}

1.4.2 避免虚函数滥用(C++)

虚函数会强制生成 vtable 和 RTTI,且难以被内联/DCE。

cpp 复制代码
// 替代方案:CRTP(Curiously Recurring Template Pattern)
template<typename Derived>
class Base {
public:
    void interface() {
        static_cast<Derived*>(this)->impl();
    }
};

class Concrete : public Base<Concrete> {
public:
    void impl() { /* 实际逻辑 */ }
};

1.4.3 字符串常量优化

c 复制代码
// ❌ 重复字符串面量导致体积膨胀
const char* a = "hello world";
const char* b = "hello world";  // 可能生成两份

// ✅ 集中管理字符串
// 使用 -fmerge-all-constants 让编译器合并
// 或自定义字符串池

// 嵌入式:压缩字符串后运行时解压
// 或使用 printf 格式字符串代替多个字面量

1.4.4 使用 [[nodiscard]]inline 控制膨胀(C++17)

cpp 复制代码
// 小型高频函数内联,避免函数调用开销同时不增加代码段
inline int clamp(int x, int lo, int hi) {
    return x < lo ? lo : x > hi ? hi : x;
}

// 大型函数明确禁止内联
__attribute__((noinline)) void heavy_init();

1.4.5 减少全局对象与静态初始化

全局 C++ 对象的构造函数会生成 .init_array 段,增加启动代码。

cpp 复制代码
// ❌ 全局对象
static std::vector<int> g_cache;   // 有构造函数

// ✅ 延迟初始化 / 使用 POD
static int g_cache[MAX_SIZE];      // POD,无构造函数
static int g_cache_size = 0;

// 或使用 constinit / constexpr(C++20)
constinit static Config g_config = {};

1.4.6 枚举与类型大小收紧

c 复制代码
// 使用尽量小的整数类型
uint8_t  status;   // 代替 int
uint16_t count;    // 代替 size_t(嵌入式场景)

// 位域
struct Flags {
    uint8_t enabled : 1;
    uint8_t mode    : 3;
    uint8_t level   : 4;
};

1.4.7 避免异常与 RTTI(C++)

cpp 复制代码
// 编译时关闭异常(-fno-exceptions)后,
// 用错误码或 std::expected 替代

std::expected<Result, Error> compute() {
    if (failed) return std::unexpected(Error::NotFound);
    return result;
}

// 或使用 outcome / tl::expected 等库

1.4.8 Rust 特有技巧

rust 复制代码
// 1. 使用 panic = "abort" 避免 panic unwind 代码
// 2. 避免动态分配(no_std 场景)
#![no_std]
#![no_main]

// 3. 减少 monomorphization:用 dyn Trait 代替泛型(用运行时成本换体积)
fn process(handler: &dyn Handler) {}   // 生成一份代码
fn process<H: Handler>(handler: &H) {} // 每个 H 生成一份

// 4. 使用 #[inline(never)] 阻止过度内联
#[inline(never)]
fn heavy_function() {}

// 5. 裁剪 std 功能
// 在 Cargo.toml 中禁用默认 features
[dependencies]
serde = { version = "1", default-features = false, features = ["derive"] }

1.5 资源与数据优化

1.5.1 资源压缩

资源类型 优化方案
PNG 图片 pngquant(有损压缩)、optipng/zopflipng(无损)
JPEG mozjpegjpegoptim
WebP 比 PNG/JPEG 更小,建议迁移
SVG svgo 去除冗余属性
音频 opus/aac 代替 mp3,适当降低比特率
视频 AV1/HEVC,或按需流式加载
字体 子集化(subsetting)、woff2 格式、pyftsubset

1.5.2 查找表(LUT)替代运算

c 复制代码
// 计算成本换体积(运行时计算 vs 静态表)
// 三角函数表、CRC 表等可预计算后编译进二进制
// 嵌入式中也可在运行时生成(RAM 换 Flash)

// 或使用 Q 格式定点数代替浮点运算,减少浮点库依赖

1.5.3 嵌入资源到二进制

bash 复制代码
# GNU ld objcopy
objcopy -I binary -O elf32-littlearm logo.png logo.o
# 生成 _binary_logo_png_start / _end / _size 符号

# CMake + xxd
xxd -i resource.bin > resource.h

1.5.4 按需加载资源

避免将所有资源打包进二进制,改为运行时按需从网络/文件系统加载:

  • Android:AAB(App Bundle)按设备配置分发资源
  • iOS:On-Demand Resources(ODR)
  • PC/服务端:DLC、资源热更新

1.6 依赖库管理

1.6.1 静态链接 vs 动态链接

维度 静态链接 动态链接
单文件体积 更大(含库代码) 更小(依赖系统库)
安装总体积 多应用共享时更大 共享库只有一份
DCE 效果 好(链接器可裁剪) 差(整个 .so 必须保留)
部署灵活性 好(无依赖) 需确保库版本兼容

结论 :若目标是单二进制小型化,优先静态链接 + --gc-sections;若目标是系统总体积,使用动态链接共享系统库。

1.6.2 替换重量级依赖

场景 重型库 轻量替代
JSON 解析 RapidJSON(功能全) jsmn、yyjson
HTTP 客户端 libcurl picohttp、llhttp
正则表达式 PCRE2 re2(精简版)、tiny-regex
日志 log4cpp spdlog(header-only)、NanoLog
压缩 zlib miniz(单文件)、lz4(更快更小)
TLS OpenSSL mbedTLS、BearSSL(嵌入式友好)
C++ 标准库 libstdc++ libc++(通常更小)、musl libc

1.6.3 使用 --as-needed 链接标志

bash 复制代码
# 只链接实际用到的动态库,不引入无用的 .so 依赖
-Wl,--as-needed

1.6.4 Rust:cargo-bloat 分析依赖贡献

bash 复制代码
cargo install cargo-bloat
cargo bloat --release --crates   # 按 crate 显示体积贡献
cargo bloat --release -n 20      # 显示最大的 20 个函数

1.6.5 Go:按需 build tags 裁剪

go 复制代码
//go:build !windows
bash 复制代码
# 排除 CGO
CGO_ENABLED=0 go build -o app .

# 仅使用纯 Go 实现的网络库
go build -tags netgo -o app .

1.7 调试信息处理

1.7.1 Strip 符号表

bash 复制代码
# 完全剥离(生产发布)
strip --strip-all output

# 仅剥离调试信息,保留符号表(可用于符号化崩溃)
strip --strip-debug output

# macOS
strip -x output        # 删除局部符号
strip -S output        # 删除调试符号

# objcopy 方式(可同时保留带调试的副本)
objcopy --only-keep-debug output output.dbg    # 提取调试信息
objcopy --strip-debug output                   # 剥离原文件
objcopy --add-gnu-debuglink=output.dbg output  # 添加链接

1.7.2 Split DWARF(DWP)

将 DWARF 调试信息拆分到独立 .dwo 文件,发布时不随二进制分发。

bash 复制代码
# GCC/Clang
-gsplit-dwarf

# 打包所有 .dwo 为一个文件
llvm-dwp -e output -o output.dwp

1.7.3 压缩调试信息(开发阶段)

bash 复制代码
# 压缩 DWARF 节,减少 debug 构建体积(不影响 release)
-gz=zlib    # GCC/Clang 支持

1.7.4 最小化发布构建

makefile 复制代码
RELEASE_FLAGS := -O2 -DNDEBUG -ffunction-sections -fdata-sections \
                 -fno-exceptions -fno-rtti -fvisibility=hidden
RELEASE_LDFLAGS := -Wl,--gc-sections -Wl,--strip-all \
                   -Wl,--icf=all -flto

1.8 平台专项优化

1.8.1 Android

1.8.1.1 R8 / ProGuard(Java/Kotlin)
groovy 复制代码
// build.gradle
android {
    buildTypes {
        release {
            minifyEnabled true       // 开启代码压缩
            shrinkResources true     // 开启资源压缩
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                         'proguard-rules.pro'
        }
    }
}
1.8.1.2 App Bundle(AAB)
bash 复制代码
# AAB 按设备 ABI / 语言 / 屏幕密度分发,避免打包所有资源
./gradlew bundleRelease
1.8.1.3 NDK 层
cmake 复制代码
# CMakeLists.txt
target_compile_options(mylib PRIVATE -Os -ffunction-sections -fdata-sections)
target_link_options(mylib PRIVATE -Wl,--gc-sections -Wl,--icf=safe)
set_target_properties(mylib PROPERTIES LINK_FLAGS "-s")  # strip
1.8.1.4 ABI 过滤
groovy 复制代码
android {
    defaultConfig {
        ndk {
            // 仅支持主流 ABI,减少包体积
            abiFilters 'arm64-v8a', 'x86_64'
        }
    }
}

1.8.2 iOS

1.8.2.1 编译器优化
复制代码
// Xcode Build Settings
SWIFT_OPTIMIZATION_LEVEL = -Osize    // Swift
GCC_OPTIMIZATION_LEVEL = s           // ObjC/C
DEAD_CODE_STRIPPING = YES
ENABLE_BITCODE = NO                  // Bitcode 已废弃,不再需要
STRIP_INSTALLED_PRODUCT = YES
STRIP_STYLE = all
1.8.2.2 Swift 特定
swift 复制代码
// 使用 @inlinable 谨慎内联,避免不必要的模块间代码复制
@inlinable public func hot_path() { ... }

// 使用 final 阻止动态派发,便于优化
final class MyService { ... }

// 开启 Whole Module Optimization
// SWIFT_WHOLE_MODULE_OPTIMIZATION = YES
1.8.2.3 On-Demand Resources

将大型资源(关卡数据、字体等)声明为 ODR,下载时才获取:

swift 复制代码
let request = NSBundleResourceRequest(tags: ["level-5"])
request.beginAccessingResources { error in ... }

1.8.3 WebAssembly

bash 复制代码
# Emscripten
emcc -Os -flto --closure 1 \
     -s FILESYSTEM=0 \
     -s ASSERTIONS=0 \
     -s MALLOC=emmalloc \   # 更小的 malloc 实现
     -o app.wasm main.c

# wasm-opt(Binaryen 后处理,额外优化)
wasm-opt -Oz --enable-mutable-globals app.wasm -o app.opt.wasm

# Rust + wasm-pack
wasm-pack build --release
wasm-opt -Oz pkg/app_bg.wasm -o pkg/app_bg.opt.wasm

1.8.4 嵌入式 / 裸机(Bare Metal)

c 复制代码
// 1. 去除 C 标准库,使用 newlib-nano 或自定义 syscall
// 链接 newlib-nano(ARM)
// --specs=nano.specs --specs=nosys.specs

// 2. 去除浮点支持(软浮点 + 不使用 libm)
-mfloat-abi=soft -mfpu=none

// 3. 自定义 startup 代码,去除未使用的初始化
// 替换 crt0.o 中的 __libc_init_array

// 4. 使用链接脚本精确控制段布局
// 将热路径函数放入 ITCM(指令紧耦合内存)
__attribute__((section(".itcm_text")))
void hot_isr_handler() {}

1.8.5 Go

bash 复制代码
# 禁用 CGO(纯 Go 二进制更小,无需 glibc)
CGO_ENABLED=0 go build -o app .

# 去除调试信息和符号表
go build -ldflags="-s -w" -o app .

# UPX 压缩(运行时自解压,冷启动有延迟)
upx --best app

# 使用 trimpath 去除源码路径(减小符号信息)
go build -trimpath -o app .

# goblin:实验性的 Go binary 小型化工具
# github.com/nicholasgasior/goblin

1.9 分析与度量工具

1.9.1 符号大小分析

bash 复制代码
# nm:列出所有符号及大小
nm --print-size --size-sort --radix=d output | tail -30

# objdump:反汇编 + 节大小
objdump -h output              # 各节大小
objdump -t output | sort -k5  # 符号排序

# size:快速查看各段大小
size output
size -A output   # 详细模式

1.9.2 专用分析工具

1.9.2.1 Bloaty McBloatface(强烈推荐)
bash 复制代码
# 安装
git clone https://github.com/google/bloaty && cd bloaty
cmake -B build && cmake --build build

# 基础分析
bloaty output

# 按编译单元分解
bloaty output -d compileunits

# 对比两个版本的差异(关键!用于 CI 中检测体积回归)
bloaty new_binary -- old_binary

# 输出 CSV 供进一步处理
bloaty output -d symbols --csv > symbols.csv
1.9.2.2 cargo-bloat(Rust)
bash 复制代码
cargo bloat --release --crates -n 20
1.9.2.3 Android 专用
bash 复制代码
# apkanalyzer(Android SDK 自带)
apkanalyzer apk summary app-release.apk
apkanalyzer dex packages app-release.apk
apkanalyzer manifest print app-release.apk
1.9.2.4 iOS 专用
bash 复制代码
# Xcode 内置 App Size Report
# Product → Archive → Distribute App → 选择 Development → 查看 App Thinning Size Report

# otool
otool -l app.o | grep -A4 "sectname"

1.9.3 可视化工具

工具 平台 功能
Bloaty 通用 层次化树形分析
Binary Size Analyzer ELF 交互式 Web 可视化
cargo-bloat Rust crate/函数级分析
Twiggy Wasm/ELF 调用图分析,找出"保活"根因
Weigh Rust 类型大小分析
Android Profiler Android APK 内容树形图
Xcode Memory Graph iOS 对象占用分析

1.9.4 段大小追踪脚本示例

python 复制代码
#!/usr/bin/env python3
# track_size.py ------ 记录每次构建的二进制大小,便于趋势分析
import subprocess, json, datetime, pathlib, os

def get_section_sizes(binary):
    out = subprocess.check_output(["size", "-A", binary]).decode()
    sizes = {}
    for line in out.splitlines()[1:]:
        parts = line.split()
        if len(parts) >= 2:
            sizes[parts[0]] = int(parts[1])
    return sizes

binary = "./build/app"
sizes = get_section_sizes(binary)
record = {
    "timestamp": datetime.datetime.utcnow().isoformat(),
    "commit": os.getenv("GIT_COMMIT", "local"),
    "total_file": pathlib.Path(binary).stat().st_size,
    "sections": sizes,
}
log = pathlib.Path("size_history.jsonl")
with log.open("a") as f:
    f.write(json.dumps(record) + "\n")
print(json.dumps(record, indent=2))

1.10 CI/CD 集成

1.10.1 体积预算(Size Budget)

在 CI 中设置阈值,超标则 fail build:

yaml 复制代码
# .github/workflows/size_check.yml
- name: Check binary size
  run: |
    SIZE=$(stat -c%s build/app)
    MAX=5242880  # 5 MB
    if [ "$SIZE" -gt "$MAX" ]; then
      echo "❌ Binary too large: ${SIZE} bytes (limit: ${MAX})"
      exit 1
    fi
    echo "✅ Binary size OK: ${SIZE} bytes"

1.10.2 PR 体积对比(Bloaty + GitHub Actions)

yaml 复制代码
- name: Compare binary size with main
  run: |
    git fetch origin main
    git checkout origin/main -- build/app
    mv build/app build/app_main
    git checkout HEAD -- build/app
    bloaty build/app -- build/app_main \
      --domain=vm -d sections 2>&1 | tee size_diff.txt
    cat size_diff.txt >> $GITHUB_STEP_SUMMARY

1.10.3 自动生成 Size Report

yaml 复制代码
- name: Generate size report
  run: |
    {
      echo "## 📦 Binary Size Report"
      echo "\`\`\`"
      bloaty build/app -d compileunits -n 20
      echo "\`\`\`"
    } >> $GITHUB_STEP_SUMMARY

1.11 各语言速查表

1.11.1 C / C++

bash 复制代码
# 编译
CFLAGS  = -Os -ffunction-sections -fdata-sections \
          -fno-exceptions -fno-rtti -fvisibility=hidden \
          -flto

# 链接
LDFLAGS = -Wl,--gc-sections -Wl,--icf=all \
          -Wl,--strip-all -fuse-ld=lld -flto \
          -Wl,--as-needed

1.11.2 Rust

toml 复制代码
# Cargo.toml
[profile.release]
opt-level = "z"
lto = "thin"
codegen-units = 1
panic = "abort"
strip = "symbols"
overflow-checks = false

1.11.3 Go

bash 复制代码
CGO_ENABLED=0 go build \
  -ldflags="-s -w" \
  -trimpath \
  -o app .

1.11.4 Swift

复制代码
SWIFT_OPTIMIZATION_LEVEL = -Osize
DEAD_CODE_STRIPPING = YES
STRIP_INSTALLED_PRODUCT = YES
SWIFT_COMPILATION_MODE = wholemodule

1.11.5 WebAssembly(Rust)

toml 复制代码
[profile.release]
opt-level = "z"
lto = true

# .cargo/config.toml
[target.wasm32-unknown-unknown]
rustflags = ["-C", "link-arg=--export-dynamic"]
bash 复制代码
wasm-opt -Oz --strip-debug input.wasm -o output.wasm

1.12 优化优先级建议

按照 投入产出比 排序,建议按此顺序逐步尝试:

优先级 措施 预期收益 风险
⭐⭐⭐⭐⭐ -Os / -Oz 优化等级 10%~30%
⭐⭐⭐⭐⭐ --gc-sections + -ffunction-sections 5%~40%
⭐⭐⭐⭐⭐ strip 调试信息 30%~60% 无(保留 .dbg)
⭐⭐⭐⭐ LTO(ThinLTO 优先) 5%~20% 中(构建变慢)
⭐⭐⭐⭐ ICF(Identical Code Folding) 3%~15%
⭐⭐⭐⭐ -fno-exceptions -fno-rtti 5%~15% 高(需代码改造)
⭐⭐⭐ 符号可见性控制 1%~5%
⭐⭐⭐ 替换重型依赖库 项目相关 高(需重测)
⭐⭐⭐ 资源压缩(图片/字体) 项目相关
⭐⭐ PGO 优化 5%~10% 高(流程复杂)
⭐⭐ 模板实例化优化 项目相关
自定义 malloc(嵌入式) 5%~20%
UPX 压缩 30%~50% 冷启动变慢

1.13 参考资料

相关推荐
weixin_446260853 小时前
软件工程工具链机制的认知模型:打造可持续、可复现的开发工作流
软件工程
Ting.~4 小时前
软件设计师备考笔记【day2】-软件工程
笔记·软件工程
互联网推荐官1 天前
上海物联网应用开发的协议选型与平台架构实践
人工智能·物联网·软件工程
j_xxx404_1 天前
我用 Codex 做了一个智能围棋机器人系统:从 AI 引擎接入到前后端联调的完整实战
c++·人工智能·python·机器人·软件工程·团队开发·react
互联网推荐官2 天前
上海APP开发公司的技术路径选择:从架构设计到工程落地
大数据·人工智能·物联网·软件工程
早日退休!!!2 天前
《软件工程之美》读书笔记
软件工程
workflower2 天前
机器人应用-高空立面清洁
人工智能·深度学习·设计模式·机器人·软件工程·软件构建
互联网推荐官2 天前
上海小程序开发的接口安全与数据通信设计:工程实践中的关键决策
大数据·人工智能·物联网·软件工程
Dola_Zou3 天前
工业软件资产货币化与全球分发实战
自动化·软件工程·软件加密