Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions benchmark/results/results-v0.2.16-20260911T011308Z.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
timestamp,version,commit,cpu,case,input,samples,kvlang_shm_ns,kvlang_fs_ns,kvlang_redis_ns,python_ns,rust_ns,c_ns,python_ver,rust_ver,c_ver,native_opt,valid
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,binary_search,N=16,3,7099193,223205369,716253222,14349,717,512,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,binary_search,N=32,3,15275688,501195152,1656970081,24010,1380,1027,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,binary_search,N=64,3,33652224,1138764433,3784256743,45918,2840,2184,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,binary_trees,depth=4,3,5282216,278127932,739482394,14223,2474,5803,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,binary_trees,depth=5,3,9883753,637170827,1483571136,22263,3132,6512,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,binary_trees,depth=6,3,19741714,1660609241,2939132713,40068,4444,8371,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,fib,n=8,3,7732204,164578012,583684588,10730,303,299,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,fib,n=9,3,12536490,261690481,876688373,12828,388,423,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,fib,n=10,3,20571007,434462225,1448044410,15200,498,588,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,hash_table,N=50,3,4790641,223979622,690915351,33785,5123,327,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,hash_table,N=100,3,9478869,549312608,1397201286,61674,8287,444,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,hash_table,N=200,3,19748149,1459993787,2769276840,112690,15610,770,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,iops,N=500,3,7751474,379145374,1598561541,23470,497,287,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,iops,N=1000,3,14960984,753124227,3111577142,45404,794,451,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,iops,N=2000,3,29944181,1474923033,6268901390,88209,1474,776,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,k_nucleotide,rep=3,3,10877880,425792743,1593215560,39363,3352,197,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,k_nucleotide,rep=5,3,21262879,700458624,2680194117,63228,4896,283,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,k_nucleotide,rep=8,3,41275509,1098307648,4196984458,98657,7428,400,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,matmul,N=4,3,3368303,273707259,668428398,20272,358,225,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,matmul,N=6,3,9842886,952503423,2119539868,52564,434,370,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,matmul,N=8,3,22320955,2733835542,4897455300,116622,724,557,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,nqueens,N=4,3,5350128,165642072,372506635,14109,325,258,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,nqueens,N=5,3,16144084,511662662,1179281110,23232,577,565,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,nqueens,N=6,3,45942985,1566409608,3445230882,50474,1501,1520,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,prime_sieve,N=50,3,12260942,504422820,2129346527,40230,15878,17671,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,prime_sieve,N=75,3,23484188,1016440944,4342725066,62068,18500,19593,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,prime_sieve,N=100,3,34097331,1488108259,6456957991,82141,21762,21318,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,quicksort,"N=32,seed=1",3,8070433,504594995,1478560168,18553,1096,1015,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,quicksort,"N=64,seed=1",3,17755186,1294659882,3412003366,33848,2294,2208,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2026-09-11T01:13:08Z,v0.2.16-9-gfb08343-dirty,fb08343,Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz,quicksort,"N=128,seed=1",3,37873522,3499084466,7528516277,66947,5173,4588,3.12.7,1.97.1,13.3.0,gcc -O1 / rustc opt-level=1 / cpython,True
2 changes: 1 addition & 1 deletion extensions/kvlang/syntaxes/kvlang.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"keyword": {
"name": "keyword.control.kvlang",
"match": "\\b(rwfunc|rwir|lib|struct|if|else|for|while|break|continue|return)\\b"
"match": "\\b(rwfunc|rwir|lib|struct|if|else|for|in|while|break|continue|return)\\b"
},
"block_label": {
"name": "entity.name.label.kvlang",
Expand Down
57 changes: 50 additions & 7 deletions layout/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub fn compile(kv: &mut Kv, src: &str) -> Result<Vec<String>, String> {
let (file, mut diags) = parser::parse_code(src)?;
for f in subscript_check_funcs(&file) {
diags.extend(lower::check_container_subscript(&f));
diags.extend(lower::check_map_defined(&f));
diags.extend(lower::check_container_typed(&f));
}
for d in &diags {
eprintln!("{}", d.string());
Expand Down Expand Up @@ -140,6 +142,8 @@ pub fn vet(src: &str) -> Result<(), String> {
let (file, mut diags) = parser::parse_code(src)?;
for f in subscript_check_funcs(&file) {
diags.extend(lower::check_container_subscript(&f));
diags.extend(lower::check_map_defined(&f));
diags.extend(lower::check_container_typed(&f));
}
for d in &diags {
eprintln!("{}", d.string());
Expand Down Expand Up @@ -458,6 +462,7 @@ struct RawInst {
opcode: String,
reads: Vec<Operand>,
writes: Vec<String>,
write_types: Vec<String>,
}

/// 操作数:引用(变量/opcode/路径)、字符串字面量、其它字面量(数值/bool)。
Expand Down Expand Up @@ -488,19 +493,23 @@ fn read_insts(kv: &mut Kv, dir: &str) -> Vec<RawInst> {
j += 1;
}
let mut writes = Vec::new();
let mut wtypes = Vec::new();
let mut j = 1;
loop {
let d = kv.get_one(&format!("{dir}[{n},{j}]"));
if d.is_empty() {
break;
}
writes.push(kvkind::rwir_sig(&d));
let (w, ty) = kvkind::write_slot_name(&d);
writes.push(w);
wtypes.push(ty);
j += 1;
}
out.push(RawInst {
opcode,
reads,
writes,
write_types: wtypes,
});
n += 1;
}
Expand Down Expand Up @@ -592,14 +601,18 @@ fn build_inst(inst: &RawInst, by_irseq: &HashMap<i32, String>) -> Instruction {
v[0] = ty;
v
} else {
Vec::new()
let mut v = inst.write_types.clone();
if v.iter().all(String::is_empty) {
v = Vec::new();
}
v
};
Instruction {
comments: Vec::new(),
expr,
writes: inst.writes.clone(),
write_types,
arrow_left: is_fill,
arrow_left: is_fill || inst.write_types.iter().any(|t| !t.is_empty()),
}
}

Expand Down Expand Up @@ -643,6 +656,15 @@ pub fn write_func(kv: &mut Kv, pkg: &str, fn_: &mut Func) {
let nr = fn_.sig.num_reads();
let nw = fn_.sig.num_writes();
let param_types: Vec<String> = fn_.sig.langtype_list();
// 形参/写参的**声明类型**:容器字面量写给带类型标注的形参时(`{…} -> m`,m:[]char/utf8·int64),
// 写槽须承载该 map langtype——否则 runtime 无从得知容器值 langtype(签名即声明处,见 [[map容器]])。
let mut param_langtype: HashMap<String, String> = HashMap::new();
for (i, p) in fn_.sig.params.iter().enumerate() {
param_langtype.insert(p.name.clone(), param_types[i].clone());
}
for (i, r) in fn_.sig.returns.iter().enumerate() {
param_langtype.insert(r.name.clone(), param_types[nr as usize + i].clone());
}

let mut pairs: Vec<(String, Vec<u8>)> = Vec::new();
pairs.push((
Expand Down Expand Up @@ -679,6 +701,7 @@ pub fn write_func(kv: &mut Kv, pkg: &str, fn_: &mut Func) {
&labels,
&mut type_map,
&param_coord,
&param_langtype,
);
}
if !labels.is_empty() {
Expand Down Expand Up @@ -824,6 +847,7 @@ fn write_linear_inst(
labels: &HashMap<String, i32>,
type_map: &mut HashMap<String, String>,
params: &HashMap<String, String>,
param_langtype: &HashMap<String, String>,
) {
for (j, w) in s.writes.iter().enumerate() {
if j < s.write_types.len() && !s.write_types[j].is_empty() {
Expand Down Expand Up @@ -871,11 +895,19 @@ fn write_linear_inst(
));
}
for (j, w) in s.writes.iter().enumerate() {
let wv = params
.get(w.as_str())
let orig = w.as_str();
let wv = params.get(orig).map(String::as_str).unwrap_or(orig);
let ty = s
.write_types
.get(j)
.map(String::as_str)
.unwrap_or(w.as_str());
pairs.push((format!("{prefix}/[{n},{}]", j + 1), slot_value(wv, "")));
.filter(|t| !t.is_empty())
.or_else(|| param_langtype.get(orig).map(String::as_str))
.unwrap_or("");
pairs.push((
format!("{prefix}/[{n},{}]", j + 1),
write_slot_value(wv, ty),
));
}
if !pairs.is_empty() {
let _ = kv.set(&pairs);
Expand Down Expand Up @@ -907,6 +939,17 @@ fn opcode_value(opcode: &str) -> Vec<u8> {
}
}

/// 写槽值:写目标带 **map langtype** 标注时(`x:{keylt}·{valt} = {}`),槽的 langtype 即该 map
/// langtype、body 即变量名——runtime 据此把容器值按 [[map容器]] 落成「langtype=map langtype、
/// storetype=index、body 空」,成员索引落兄弟槽 `x·`。其余写槽仍是 rwir 引用(body 带计数头)。
/// 参数替换过的写槽(rwfunc 写参轴)不承载类型:声明类型已落 `/lib/<fn>.[0,k]` 参数定义键。
fn write_slot_value(name: &str, ty: &str) -> Vec<u8> {
if ty.contains(keytree::MEMBER_SEP) {
return ffi::tlv_encode(ty, name.as_bytes(), 1);
}
slot_value(name, "")
}

/// 将字面量/引用字符串编码为 XValue TLV(rwir 槽值)。
fn slot_value(val: &str, target_char: &str) -> Vec<u8> {
if !is_literal(val) {
Expand Down
45 changes: 37 additions & 8 deletions layout/src/kvkind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,32 @@ pub fn head(data: &[u8]) -> ffi::kvspaceHead_t {
}

/// 解析 langtype 内容 → (dims, base kind)。langtype 无前缀(ref/ptr 归 head.ref)。
/// **map langtype 无形状段**:`{keylt}·{valt}` 里 `·` 之前的方括号是键类型(`[int64]`、
/// `[float64,float64]`),不是维度——与 `[2]float64`(数组形状)截然不同,故整串即基 kind。
/// 非 map 串也只把**纯数字/空/?**的方括号当形状(见 [[map容器]])。
pub fn parse_langtype(kx: &str) -> (Vec<i32>, String) {
if kx.contains(super::keytree::MEMBER_SEP) {
return (Vec::new(), kx.to_string());
}
if kx.starts_with('[') {
match kx.find(']') {
Some(end) => (
kx[1..end]
.split(',')
.filter(|d| !d.is_empty())
.map(|d| d.parse().unwrap_or(0))
.collect(),
kx[end + 1..].to_string(),
),
Some(end) => {
let inner = &kx[1..end];
if inner.split(',').all(|d| {
let d = d.trim();
d.is_empty() || d == "?" || d.parse::<i32>().is_ok()
}) {
return (
inner
.split(',')
.filter(|d| !d.is_empty())
.map(|d| d.parse().unwrap_or(0))
.collect(),
kx[end + 1..].to_string(),
);
}
(Vec::new(), kx.to_string())
}
None => (Vec::new(), kx.to_string()),
}
} else {
Expand Down Expand Up @@ -354,6 +369,20 @@ pub fn plain(data: &[u8]) -> String {
}

/// rwir 族槽值的载荷串(opcode / 引用名):body 去 5 字节计数头后的字节。
/// 写槽值 → (名字, 声明类型):写目标带 map langtype 标注(`x:{keylt}·{valt} = {}`)时,槽的
/// langtype 即该 map langtype、body 即变量名(见 [[map容器]]);其余写槽走 rwir 引用载荷
/// (跳过 5B 计数头)。dump 逆向时据此还原 `-> x:<type>`,使 round-trip 不丢容器类型。
pub fn write_slot_name(data: &[u8]) -> (String, String) {
if data.is_empty() {
return (String::new(), String::new());
}
let k = kind(data);
if k.contains(super::keytree::MEMBER_SEP) {
return (value_string(data), k);
}
(rwir_sig(data), String::new())
}

pub fn rwir_sig(data: &[u8]) -> String {
if data.is_empty() {
return String::new();
Expand Down
14 changes: 12 additions & 2 deletions layout/src/langtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,14 @@ fn valid_structref(s: &str) -> bool {
Some(r) => r,
None => return false,
};
// 段名字符集与**标识符**同一套(见 scanner::is_token_delim)——否则 `点` 这类 CJK
// struct 名能作标识符、能作 struct 名,却单单不能出现在参数/返回的类型位置。
!rest.is_empty()
&& rest.split('/').all(|seg| {
!seg.is_empty() && seg.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'_')
!seg.is_empty()
&& seg
.bytes()
.all(|b| !super::scanner::is_token_delim(b) && b != b'"' && b != b'\'')
})
}

Expand Down Expand Up @@ -161,7 +166,9 @@ fn valid_key(s: &str) -> bool {
/// atom = shape | mapexpr | structref;mapexpr = key "·" type;structref = "/" path。
/// 最前 `*` 是 ref 前缀(Ptr 存储位置),校验剥离后剩余部分(见 [[类型表达式文法]])。
fn valid_atom(s: &str) -> bool {
if let Some(rest) = s.strip_prefix('*') {
// `*`=ref ptr、`@`=ref @ext(见 [[ref存储位置]]):两者都只是**源码**前缀,
// layout 解析时剥离并落成 head.ref 字节,wire langtype 不含前缀。
if let Some(rest) = s.strip_prefix('*').or_else(|| s.strip_prefix('@')) {
return !rest.is_empty() && valid_atom(rest);
}
if s.starts_with('/') {
Expand Down Expand Up @@ -189,6 +196,9 @@ fn expand_atom(s: &str) -> String {
if let Some(rest) = s.strip_prefix('*') {
return format!("*{}", expand_atom(rest));
}
if let Some(rest) = s.strip_prefix('@') {
return format!("@{}", expand_atom(rest));
}
if s.starts_with('/') {
return s.to_string();
}
Expand Down
Loading
Loading