Skip to content

Commit c07b788

Browse files
committed
update
1 parent 7ce738f commit c07b788

File tree

6 files changed

+41
-19
lines changed

6 files changed

+41
-19
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/luars/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ loadlib = ["dep:libloading"]
1313
emmylua_parser.workspace = true
1414
libloading = { workspace = true, optional = true }
1515
tokio = { workspace = true, optional = true }
16+
itoa = "1.0" # Fast integer formatting (10x faster than format!)
17+
ryu = "1.0" # Fast float formatting

crates/luars/src/lua_vm/dispatcher/upvalue_instructions.rs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -194,33 +194,47 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
194194
let frame = vm.current_frame();
195195
let base_ptr = frame.base_ptr;
196196

197-
// Fast path: collect all strings/numbers first
198-
let mut all_strings = true;
199-
let mut temp_strings: Vec<String> = Vec::with_capacity(b + 1);
197+
// ULTRA-OPTIMIZED: Build result string directly without intermediate allocations
198+
// Estimate total capacity and format numbers inline with itoa
199+
let mut total_capacity = 0usize;
200+
let mut all_simple = true;
200201

202+
// First pass: check types and estimate capacity
201203
for i in 0..=b {
202204
let value = vm.register_stack[base_ptr + a + i];
203205

204206
if let Some(s) = value.as_lua_string() {
205-
temp_strings.push(s.as_str().to_string());
206-
} else if let Some(int_val) = value.as_integer() {
207-
temp_strings.push(int_val.to_string());
208-
} else if let Some(float_val) = value.as_number() {
209-
temp_strings.push(float_val.to_string());
207+
total_capacity += s.as_str().len();
208+
} else if value.is_integer() {
209+
total_capacity += 20; // Max digits for i64
210+
} else if value.is_number() {
211+
total_capacity += 30; // Max digits for f64
210212
} else {
211-
all_strings = false;
213+
all_simple = false;
212214
break;
213215
}
214216
}
215217

216-
// Fast path: all strings/numbers, no metamethods needed
217-
if all_strings && !temp_strings.is_empty() {
218-
// Calculate total length for pre-allocation
219-
let total_len: usize = temp_strings.iter().map(|s| s.len()).sum();
220-
let mut result = String::with_capacity(total_len);
221-
for s in temp_strings {
222-
result.push_str(&s);
218+
// Fast path: all strings/numbers, concatenate directly
219+
if all_simple {
220+
let mut result = String::with_capacity(total_capacity);
221+
let mut int_buffer = itoa::Buffer::new();
222+
let mut float_buffer = ryu::Buffer::new();
223+
224+
for i in 0..=b {
225+
let value = vm.register_stack[base_ptr + a + i];
226+
227+
if let Some(s) = value.as_lua_string() {
228+
result.push_str(s.as_str());
229+
} else if let Some(int_val) = value.as_integer() {
230+
// OPTIMIZED: Direct formatting with itoa
231+
result.push_str(int_buffer.format(int_val));
232+
} else if let Some(float_val) = value.as_number() {
233+
// OPTIMIZED: Direct formatting with ryu
234+
result.push_str(float_buffer.format(float_val));
235+
}
223236
}
237+
224238
let result_value = vm.create_string(&result);
225239
vm.register_stack[base_ptr + a] = result_value;
226240
return Ok(());

crates/luars/src/lua_vm/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,7 @@ impl LuaVM {
11901190
.unwrap_or(std::ptr::null());
11911191
LuaValue::string_id_ptr(id, ptr)
11921192
}
1193-
1193+
11941194
/// Get string by LuaValue (resolves ID from object pool)
11951195
pub fn get_string(&self, value: &LuaValue) -> Option<&LuaString> {
11961196
if let Some(id) = value.as_string_id() {

crates/luars/src/object_pool.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{LuaFunction, LuaString, LuaTable};
77
use std::cell::RefCell;
88
use std::collections::HashMap;
99
use std::rc::Rc;
10+
use std::hash::Hash;
1011

1112
/// Slot-based storage with free list for O(1) allocation and deallocation
1213
struct SlotVec<T> {
@@ -210,7 +211,7 @@ impl ObjectPool {
210211
StringId(slot_id)
211212
}
212213
}
213-
214+
214215
/// Get string by ID
215216
#[inline]
216217
pub fn get_string(&self, id: StringId) -> Option<&Rc<LuaString>> {

crates/luars/src/stdlib/basic.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,10 @@ fn lua_tostring(vm: &mut LuaVM) -> LuaResult<MultiValue> {
170170
}
171171

172172
if let Some(i) = value.as_integer() {
173-
let result = vm.create_string(&i.to_string());
173+
// OPTIMIZED: Use itoa for fast integer formatting (10x faster than format!)
174+
let mut buffer = itoa::Buffer::new();
175+
let s = buffer.format(i);
176+
let result = vm.create_string(s);
174177
return Ok(MultiValue::single(result));
175178
}
176179

0 commit comments

Comments
 (0)