新闻详情

新闻详情

首页 / 资讯中心 / 详情

BAML 基准测试 Workload 深度解析:string::split short literal 100k 与字符串 split 性能测试

发布时间:2026/9/25 7:24:20来源:尧图网络
BAML 基准测试 Workload 深度解析:string::split short literal 100k 与字符串 split 性能测试
编程语言AI Agent编译器CLI人工智能【免费下载链接】bamlThe programming language for agents项目地址https://gitcode.com/gh_mirrors/ba/baml点击查看免费下载本篇文章以仓库 baml_language/tools/speedtest 中的 Workload 定义文件 split-short-literal-100k.md 为核心完整剖析 BAML 性能基准测试中字符串按分隔符拆分这一测试场景的写法、模板注入机制、跨语言结果校验流程以及底层 bex_vm 中split的零拷贝实现原理。读完本文你将掌握 speedtest 的 Workload 文件格式与 CLI 用法并能看懂 BAML 与 Python/TypeScript 在同一计算负载下的性能对比是如何被设计、运行和核验的。一、Workload 是什么speedtest 基准测试的测试用例格式BAML 仓库自带一套跨语言性能基准工具 speedtestPython 实现入口位于 cli.py。它并不在代码里硬编码基准用例而是把每个用例定义为独立的 Markdown 文件统一存放在baml_language/tools/speedtest/workloads/下按类别分子目录classes/方法调用、方法链compute/斐波那契、冒泡排序、二叉树、闭包、协程等计算密集用例concurrency/并行 sleep、并行 sum、共享数组interfaces/多态分发、字段访问、match 分发string/字符串拼接、contains、split、substring、trim每个 Workload 文件同时给出同一逻辑负载在三种语言中的等价实现BAML、Python、TypeScript。speedtest 会依次编译并运行它们最终输出 BAML 与 Python/Node/Bun 的耗时对比与倍率。本篇文章的主角string::split short literal 100k位于 string/ 目录属于字符串类别。它的测试目标非常聚焦对一个极短的字面量字符串反复执行split并累加结果长度迭代 10 万次用来考察字符串拆分操作在热循环中的开销。其完整原文如下四段式结构这是所有 Workload 的统一骨架# string::split short literal 100k ## eval-setup py import json src hello world foo bar baz qux delim baml_src json.dumps(src) baml_delim json.dumps(delim) py_src repr(src) py_delim repr(delim) js_src json.dumps(src) js_delim json.dumps(delim) ## BAML baml function main() - int { let s $$baml_src; let delim $$baml_delim; let count 0; for (let i 0; i 100000; i 1) { let parts s.split(delim); count parts.length(); }; return count; } ## Python python s $$py_src delim $$py_delim c 0 for _ in range(100000): c len(s.split(delim)) print(c) ## Typescript ts const s $$js_src; const delim $$js_delim; let c 0; for(let i0;i100000;i) c s.split(delim).length; console.log(c); 四个段落的职责分别是段落语言作用## eval-setupPython生成测试数据为后续各语言代码注入字面量## BAMLBAML被测语言的等价实现输出int结果## PythonPython对照实现print结果## TypescriptTypeScript对照实现console.log结果Workload 的解析由 loader.py 完成标题行# ...成为 Workload 名称文件所在父目录名成为类别category path.parent.name四个代码块按小节名被提取并做模板替换。二、eval-setup$$模板注入机制与跨语言转义Workload 文件的关键设计是eval-setup 段只执行一次 Python 代码把变量注入后续三个语言的代码模板。loader.py 中定义了以$$为定界符的模板类class _DDTemplate(Template): Template using $$var instead of $var, so single $ is literal. delimiter $$选择$$作为定界符而非$是为了让模板正文中出现的单个$如字符串内容里的$符号保持字面含义不会被误当作占位符。解析流程loader.py用正则 ^##\s([\w-])\s*\n\w*\n(.*?) 切出各段代码对eval-setup段执行exec(setup, ...)把baml_src、baml_delim、py_src、py_delim、js_src、js_delim等变量装入命名空间用_DDTemplate(code).safe_substitute(namespace)对 BAML/Python/TypeScript 三段做替换得到真正可运行的源码。eval-setup 中针对不同目标语言选用了不同的序列化函数这是有讲究的BAML 与 TypeScript 用json.dumps产生双引号字符串BAML 字面量语法与 JSON 字符串语法一致可直接嵌入Python 用repr产生带单引号的 Python 字面量且对反斜杠等字符的转义方式与 Python 语法严格匹配。json.dumps/repr同时保证特殊字符引号、换行、反斜杠在目标语言中不会被破坏因此同一份 eval-setup 可以安全地把同一数据注入三种语法体系。对本用例而言注入后的 BAML 代码等价于let s hello world foo bar baz qux;、let delim ;。被测字符串含 5 个空格按 拆分恰好得到6 段因此三轮语言的最终输出都是100000 × 6 600000——这个可预先计算的期望值正是下一节跨语言校验的依据。三、BAML 实现逐行解读与 Python/TypeScript 对照BAML 侧function main() - int { let s $$baml_src; // hello world foo bar baz qux let delim $$baml_delim; // let count 0; for (let i 0; i 100000; i 1) { let parts s.split(delim); count parts.length(); }; return count; }function main() - intWorkload 约定入口函数名为main返回intrunner 通过baml-cli pack main将其打包为可执行文件运行时取 stdout 最后一行作为结果let parts s.split(delim)调用 BAML 字符串方法split返回字符串数组parts.length()数组长度外层 10 万次循环保证每次调用都真实执行BAML 编译器不会把循环内与循环外无关的计算折叠掉从而保证被测的是热路径本身。Python 侧s $$py_src delim $$py_delim c 0 for _ in range(100000): c len(s.split(delim)) print(c)Python 的str.split(delim)与 BAML 的s.split(delim)语义对齐都按字符串分隔符切分、返回列表len()取长度。TypeScript 侧const s $$js_src; const delim $$js_delim; let c 0; for(let i0;i100000;i) c s.split(delim).length; console.log(c);TypeScript 的String.prototype.split同样返回数组length取长度。三段代码的负载结构完全同构同一字符串、同一分隔符、同一迭代次数、同一累加逻辑这是后续跨语言公平对比的前提。与内联字面量变体的区别string 类别下还有一个不依赖 eval-setup 的变体 string-split-100k.md它没有## eval-setup段直接把字面量写死在各语言代码中BAML 里let s hello world foo bar baz qux;。区别在于本用例通过模板注入保证三份代码拿到的是同一份经转义的数据内联变体省去了注入环节更贴近源码中直接写死字面量的常见写法也少了一层解释器解析开销。两类用例互为补充共同覆盖字面量来自变量与字面量写死在源码两种真实场景。四、从 Workload 到基准结果runner 的完整流水线Workload 文件只是配方真正的执行与计时在 runner.py 中完成主要分四步1. 打包 BAML 为独立可执行文件def pack_baml(binary, baml_file, output_path): result subprocess.run( [binary, pack, main, --file, baml_file, -o, output_path], ... )runner 调用baml-cli pack mainrunner.py把 BAML 源码连同main入口编译打包成独立二进制后续计时直接运行该二进制排除了解释启动与源码解析的干扰。2. 跨语言输出一致性校验基准测试的第一道关卡是正确性如果 BAML 的输出与 Python/Node/Bun 不一致说明三个实现并未执行同一语义测出的耗时对比毫无意义。runner 会依次运行打包后的 BAML、python3 -S、node、bun取各自 stdout 最后一行对比runner.pyfor lang, cmd in checks: out get_output(cmd) if out is not None and out ! expected: sys.stderr.write(f MISMATCH: baml{expected}, {lang}{out}\n) row[mismatch] True若出现MISMATCH该行结果会被标记(!)。对本用例而言三者都应输出600000。3. 自适应计时与固定次数计时计时分两种模式runner.py自适应模式默认目标测量时长为--measurement-time默认 5 秒。先丢弃 3 次预热运行预热 OS 缓存/CPU用预热中位数估算单次耗时再反推需要采样的次数并夹取到[min_samples5, max_samples100]固定次数模式--runs N指定每个 Workload 固定跑 N 次。结果以中位数median为准同时记录标准差、样本数与 min/max最终汇总为 Markdown 表格列Benchmark、baml、python3、baml/py、node、baml/node、bun、baml/bun并按类别分组展示。4. 保存结果与基线每次运行的数据会存入结果目录默认~/.speedtest/并更新baselines/branch/latest可用--tag打标签类似基准的 git tag。同时支持--profile samply 对 profiling 版 baml-cli 录制 CPU 火焰图数据。相关 CLI 参数参数说明默认值--build先cargo build --release -p baml_pack_host -p baml_cli再测关闭--filter只运行名称包含子串的 Workload可重复指定全部--only-baml跳过 python/node/bun只测 BAML关闭--runs N固定采样次数覆盖自适应计时自适应--measurement-time SECS每个 Workload 自适应计时的目标秒数5.0--baml PATH指定 baml-cli 路径默认target/release/baml-cli自动探测--tag NAME给本次运行打标签无--profile/--profile-baml用 samply 录制 BAML profiling 火焰图关闭--results-dir PATH结果保存目录~/.speedtest/CLI 定义见 cli.py还提供compare、open、list、baselines子命令。例如只跑本用例speedtest run --filter split-short-literal-100k --build五、源码原理bex_vm 中零拷贝zero-copy的 split 实现为什么这个基准值得专门测因为 BAML 的split不是普通的切完复制实现而是零拷贝切片。实现在 bex_vm/src/package_baml/string.rs// Zero-copy: each segment is a zero-copy substring Slice into the original. fn split(string: BexStr, delimiter: BexStr) - VecBexStr { let s string.as_str(); let d delimiter.as_str(); if d.is_empty() { return char_substrings(string); } let base s.as_ptr() as usize; s.split(d) .map(|part| { let start part.as_ptr() as usize - base; string.substring(start, start part.len()) }) .collect() }关键细节基于 Rust 标准库str::split按分隔符迭代出各段str指针算术定位用part.as_ptr() - base计算出每个切片段在原字符串中的字节偏移再调用substring零拷贝切片BexStr内部是Inline / Flat / Slice / Concat四变体枚举见 bex_str.rs其中Slice持有一个始终是 Flat 的 parent、offset与len不复制字节内容只记录视图元数据空分隔符特判delimiter为空时按char_indices切分成单个字符子串char_substrings与常见语言中空分隔符按字符切分的语义一致。这意味着在本用例的 10 万次循环里每次s.split(delim)都不产生字符串内容的拷贝——切出来的 6 段都是指向原字面量的Slice视图内存分配被大幅压缩bex_str/src/tests.rs中也直接以matches!(s1, BexStr::Slice { .. })断言切片结果见 tests.rs。这也解释了为什么基准要同时跑string-split-100k字面量写死与split-short-literal-100k字面量来自模板变量——两者在是否能走内联/切片优化路径上存在细微差异需要分别测量。六、分档设计与其他 string 类别 Workload 的横向对比split基准在 string 类别下按字面量长度 × 迭代次数分了三档形成一组受控变量实验Workload 文件被测字符串分隔符迭代次数每轮切分段数split-short-literal-100k.mdhello world foo bar baz qux短 100,0006split-medium-literal-10k.md8 个 chunk 以\|连接中\|10,0008split-long-literal-1k.md10 个长 chunk 以###连接长###1,00010三档保持切分段数同一量级同时让单次 split 扫描的字节数递增、迭代次数递减从而把拆分短字符串的调用开销与拆分长字符串的扫描开销分开量化——前者主要考验函数调用/数组分配/切片视图构造后者主要考验字符串扫描本身。这也是 string/ 目录 整体命名规范short/medium/long 迭代次数的设计意图用可控变量拆解性能瓶颈。七、运行、对比与结果解读单跑本用例# 先构建 baml-cli 与 pack_host再只跑本 Workload speedtest run --build --filter split-short-literal-100k # 跳过对照语言只看 BAML 自身耗时 speedtest run --only-baml --filter split-short-literal-100k # 固定采样 10 次覆盖自适应计时 speedtest run --filter split-short-literal-100k --runs 10两次运行对比speedtest run --tag before # 打基线标签 speedtest run --tag after # 改动后再次运行 speedtest compare before aftercompare采用 critcmp 风格的终端 diffcompare.py按类别分组展示两轮的中位数、变化百分比用统计显著性标记sig_marker基于中位数与标准差与5%阈值区分显著变化/噪声变化若两份记录的 BAML 源码不一致还会标注(src changed)防止拿不同代码比出无意义结果。compare还内置_render_md路径可直接输出 Markdown 表格便于贴进文档或 CI 报告。读取结果speedtest list # 列出全部 Workload 名称 speedtest baselines # 查看已保存的基线 speedtest open # 打开浏览器 UI 查看结果小结string::split short literal 100k是 BAML 性能基准体系中一个典型的最小化受控用例它用四段式 Markdown 同时承载 BAML、Python、TypeScript 三种等价实现通过$$模板机制与json.dumps/repr转义保证三端拿到同一数据再经 runner 的打包、跨语言输出校验、自适应计时与基线存档最终量化 BAML 在短字符串高频拆分场景下的相对性能。配合 bex_vm 的零拷贝 split 实现 与 BexStr 切片设计这套基准不仅能回答快不快更能解释为什么快——这正是它的设计价值所在。赞分享编程语言AI Agent编译器CLI人工智能【免费下载链接】bamlThe programming language for agents项目地址https://gitcode.com/gh_mirrors/ba/baml点击查看免费下载相关推荐Rakam-API高级功能Webhook集成与实时事件处理Rakam API高级功能Webhook集成与实时事件处理 在当今数据驱动的世界中 实时事件处理 和 Webhook集成 已成为现代应用分析的核心需求编程语言AI Agent编译器CLI人工智能3小时做出会回应的虚拟桌宠VPet零基础定制完整指南3小时做出会回应的虚拟桌宠VPet零基础定制完整指南 你可能不知道一只桌宠的全部生命就是一堆 PNG 图片和几行文本配置。VPet Simulator桌面应用游戏开发awesome-computer-vision 资源获取完整指南一份清单搞定论文、数据集与工具库awesome computer vision 资源获取完整指南一份清单搞定论文、数据集与工具库 刚进入计算机视觉CV方向时你大概率遇到过这种状况论文编程语言AI Agent编译器CLI人工智能上一篇CANN Ascend C权重形状设置API下一篇Applera1n iOS激活锁绕过工具终极完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

使用 AWS SDK for Java 2.x 操作 AWS HealthImaging:数据存储、DICOM 导入与影像集管理实战指南 2026/9/25 8:02:37

使用 AWS SDK for Java 2.x 操作 AWS HealthImaging:数据存储、DICOM 导入与影像集管理实战指南

示例工程教程后端 【免费下载链接】aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. 项目地…

阅读更多 →
Atlas 300V Pro 24G部署YOLO全流程:从推理加速卡选型到昇腾NPU实战 2026/9/25 8:02:37

Atlas 300V Pro 24G部署YOLO全流程:从推理加速卡选型到昇腾NPU实战

最近几天,后台和微信私信里问得最多的就是两个问题:Atlas 300V Pro 24G到底算不算一块“运算加速卡”?以及能不能用它来部署YOLO模型?我一开始没太当回事,觉得这是昇腾生态里的老问题,结果看得多了才发现&a…

阅读更多 →
Atlas 300V 24G实战:YOLOv5/YOLOv8模型转换与推理部署全指南 2026/9/25 8:02:37

Atlas 300V 24G实战:YOLOv5/YOLOv8模型转换与推理部署全指南

最近在搞目标检测服务迁移,手头正好有一批Atlas 300V 24G推理加速卡。说实话,一开始我对这类NPU卡是有偏见的,毕竟训练和调优都在GPU上跑习惯了,换到华为的这套工具链,总感觉要先“脱层皮”。但真正把YOLOv5和YOLOv8的…

阅读更多 →
企业流程管理数字化转型:从流程建模到运营优化的落地指南 2026/9/25 8:02:11

企业流程管理数字化转型:从流程建模到运营优化的落地指南

简介:一份关于企业流程管理的数字智慧方案PPT,共76页,面向企业管理者、流程优化人员及数字化转型相关从业者,系统讲解如何通过流程管理打破部门壁垒、提升组织效率。资源为1个pptx文件,压缩包约814KB。整套内容按七大模…

阅读更多 →
VulnTarget-B综合靶机渗透测试实战:从信息收集到提权全流程解析 2026/9/25 8:02:11

VulnTarget-B综合靶机渗透测试实战:从信息收集到提权全流程解析

VulnTarget-B 是我搭在自己实验环境里的一台综合靶机,主要用来练手渗透测试全流程。最近又完整地把它打了一遍,从信息收集到内网提权、权限维持、痕迹清理都走了个遍,顺手把报告整理了出来。这篇文章就相当于把“进攻路径”从头讲一遍&#x…

阅读更多 →
楚慧杯初赛Writeup:从SQL注入绕过到隐写与RSA攻击的CTF实战 2026/9/25 8:02:11

楚慧杯初赛Writeup:从SQL注入绕过到隐写与RSA攻击的CTF实战

第十届“楚慧杯”初赛考完那天晚上,我在群里看到好几个参赛队都在问同一道Web题,当时心里就有点数了——今年的初赛跟往年不一样,题目明显往实战对抗和数据安全方向倾斜了。趁着Flag的截图和解题脚本还没吃灰,我把整场参赛过程的思…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉