Skip to content

Commit 6efb8cd

Browse files
Optimization sweep: cleanup warnings + 16 #[inline] hot-path attributes
Part of the 200+ optimization campaign. Two clusters: CLEANUP (16 mods): - Remove unused imports in evolution.rs (GateId, HashMap, RandomState, BuildHasher, Hasher) and hbit.rs (HInt) - Underscore-prefix unused gate_map params in optimizer.rs - Remove orphaned doc comment that wasn't attached to any item - Rename pyo3 _bound deprecations: import/eval/run/PyList::empty/ PyDict::new/PyTuple::new - Fix CString to as_c_str() for new pyo3 0.23 eval/run signatures - Fix PyTuple::new -> Result; remove redundant Ok wrap - Add #[allow(deprecated)] for the 2 remaining IntoPy::into_py warnings (full IntoPyObject migration is its own task) PERF (24 mods, all #[inline] annotations + 1 fast-path): - phi_pi_fib::nearest_attractor_with_dist: small-value fast-path (skip binary search for |v| <= 3, which are themselves attractors). Common in OMC hot loops (counters, small indices). - phi_pi_fib::{nearest_attractor_with_dist, fold_to_nearest_attractor, is_on_fibonacci_attractor}: #[inline] - HInt::{new, compute_resonance, compute_him, singularity}: #[inline]. Called in every harmonic int op. - HArray::{from_vec, len, is_empty}: #[inline] - Value::{dict_from, dict_empty, to_int, to_float, to_bool, is_float, is_numeric, is_singularity}: #[inline] - 5 NEW Value::is_* helpers (is_int, is_string, is_array, is_dict, is_null) — currently dispatchers use matches!() inline; these expose the same checks with consistent naming for callers that want to pre-check before extracting Tests: 149/149 omnimcode-core unit tests still pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 690d1ec commit 6efb8cd

7 files changed

Lines changed: 81 additions & 26 deletions

File tree

omnimcode-core/src/evolution.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// src/evolution.rs - Genetic algorithm operators for circuit evolution
22

3-
use crate::circuits::{Circuit, Gate, GateId};
4-
use std::collections::HashMap;
3+
use crate::circuits::{Circuit, Gate};
54

65
/// Genetic algorithm parameters
76
#[derive(Clone, Debug)]
@@ -44,9 +43,6 @@ pub fn evaluate_fitness(circuit: &Circuit, test_cases: &[TestCase]) -> f64 {
4443

4544
/// Mutate a circuit by randomly modifying gates
4645
pub fn mutate_circuit(circuit: &Circuit, mutation_rate: f64) -> Circuit {
47-
use std::collections::hash_map::RandomState;
48-
use std::hash::{BuildHasher, Hasher};
49-
5046
let mut mutated = circuit.clone();
5147

5248
// Simple RNG using time-based seed (would use rand crate in production)

omnimcode-core/src/hbit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// src/hbit.rs - HBit (Harmonic Bit) Processing Engine (FIXED)
22
// Dual-band computation with harmonic coherence tracking
33

4-
use crate::value::{HInt, PHI};
4+
use crate::value::PHI;
55
use std::collections::HashMap;
66

77
/// HBit Processor - Manages dual-band variables and harmony tracking

omnimcode-core/src/interpreter.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5019,12 +5019,6 @@ fn vm_fast_dispatch(name: &str, args: &[Value]) -> Option<Result<Value, String>>
50195019
}
50205020
}
50215021

5022-
/// Render a function name for display in stack traces. Internal
5023-
/// auto-generated lambda identifiers (`__rt_lambda_N` from the tree-
5024-
/// walk evaluator, `__lambda_N` from the bytecode compiler) collapse
5025-
/// to a single "<lambda>" so traces don't leak the implementation
5026-
/// detail of which engine assigned the counter — and so traces stay
5027-
/// stable across tree-walk vs VM runs.
50285022
// ===========================================================================
50295023
// Active-interpreter pointer for reentrant host calls.
50305024
//

omnimcode-core/src/optimizer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ impl CircuitOptimizer {
188188
fn get_gate_constant_value(
189189
&self,
190190
gate_id: GateId,
191-
gate_map: &HashMap<GateId, GateId>,
191+
_gate_map: &HashMap<GateId, GateId>,
192192
circuit: &Circuit,
193193
) -> Option<bool> {
194194
if gate_id >= circuit.gates.len() {
@@ -302,7 +302,7 @@ impl CircuitOptimizer {
302302
fn try_simplify_gate(
303303
&self,
304304
gate: &Gate,
305-
gate_map: &HashMap<GateId, GateId>,
305+
_gate_map: &HashMap<GateId, GateId>,
306306
circuit: &Circuit,
307307
) -> Option<SimplifyResult> {
308308
match gate {

omnimcode-core/src/phi_pi_fib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,11 +397,20 @@ pub fn binary_search<T>(
397397
/// Tie-break: when two attractors are equidistant, the LOWER one wins
398398
/// (matches the original linear-scan semantics: first match in
399399
/// ascending order).
400+
#[inline]
400401
pub fn nearest_attractor_with_dist(value: i64) -> (i64, i64) {
401402
let abs_v = value.abs();
402403
if abs_v == 0 {
403404
return (0, 0);
404405
}
406+
// Fast path: very small values (1, 2, 3) — extremely common in OMC
407+
// hot loops (loop counters, small indices). Skip the fibonacci_search
408+
// entirely and return inline. Catches 0/1/2/3 (which are themselves
409+
// attractors) without paying for the binary search.
410+
if abs_v <= 3 {
411+
let signed = if value < 0 { -abs_v } else { abs_v };
412+
return (signed, 0);
413+
}
405414
let target = abs_v as u64;
406415
// Substrate-internal call — book against the BACKGROUND counters
407416
// so explicit OMC searches stay separately measurable.
@@ -434,12 +443,14 @@ pub fn nearest_attractor_with_dist(value: i64) -> (i64, i64) {
434443
/// fold_to_nearest_attractor(value) — sign-preserving fold to the
435444
/// closest Fibonacci attractor. Wrapper around
436445
/// `nearest_attractor_with_dist` that discards the distance.
446+
#[inline]
437447
pub fn fold_to_nearest_attractor(value: i64) -> i64 {
438448
nearest_attractor_with_dist(value).0
439449
}
440450

441451
/// is_on_fibonacci_attractor(value) — true iff |value| is exactly a
442452
/// Fibonacci number in the canonical attractor table.
453+
#[inline]
443454
pub fn is_on_fibonacci_attractor(value: i64) -> bool {
444455
nearest_attractor_with_dist(value).1 == 0
445456
}

omnimcode-core/src/python_embed.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ fn is_handle(id: i64) -> bool {
8080

8181
/// OMC Value → Python object (pyo3 0.21 API: `.to_object(py)` and
8282
/// `.into_py(py)` are the canonical conversions).
83+
///
84+
/// pyo3 0.23 deprecated `.into_py()` in favor of `IntoPyObject::into_pyobject`,
85+
/// which is a substantive API change (returns Bound<'py, _> + Error type
86+
/// instead of PyObject). Migration is tracked but suppressed here so the
87+
/// rename-class deprecations elsewhere can land cleanly. See
88+
/// https://pyo3.rs/v0.23.0/migration for the full migration story.
89+
#[allow(deprecated)]
8390
fn omc_to_py(py: Python<'_>, v: &Value) -> PyResult<PyObject> {
8491
match v {
8592
Value::HInt(h) => {
@@ -100,14 +107,14 @@ fn omc_to_py(py: Python<'_>, v: &Value) -> PyResult<PyObject> {
100107
Value::Null => Ok(py.None()),
101108
Value::Array(arr) => {
102109
let items = arr.items.borrow();
103-
let list = PyList::empty_bound(py);
110+
let list = PyList::empty(py);
104111
for item in items.iter() {
105112
list.append(omc_to_py(py, item)?)?;
106113
}
107114
Ok(list.into_py(py))
108115
}
109116
Value::Dict(d) => {
110-
let dict = PyDict::new_bound(py);
117+
let dict = PyDict::new(py);
111118
for (k, val) in d.borrow().iter() {
112119
dict.set_item(k, omc_to_py(py, val)?)?;
113120
}
@@ -191,10 +198,11 @@ fn arr_to_py_tuple<'py>(py: Python<'py>, arr_arg: &Value) -> PyResult<Bound<'py,
191198
}
192199
other => vec![omc_to_py(py, other)?],
193200
};
194-
Ok(PyTuple::new_bound(py, items))
201+
PyTuple::new(py, items)
195202
}
196203

197204
/// Register the py_* builtin family on `interp`. After this:
205+
#[allow(deprecated)] // pyo3 0.23 IntoPy migration deferred — see omc_to_py
198206
///
199207
/// py_import("numpy") → handle
200208
/// py_call(handle, "method", a) → Value
@@ -216,7 +224,7 @@ pub fn register_python_builtins(interp: &mut Interpreter) {
216224
let name = args[0].to_display_string();
217225
Python::with_gil(|py| {
218226
let module = py
219-
.import_bound(name.as_str())
227+
.import(name.as_str())
220228
.map_err(|e| format!("py_import({}): {}", name, e))?;
221229
Ok(Value::HInt(HInt::new(store_handle(module.into_py(py)))))
222230
})
@@ -325,7 +333,7 @@ pub fn register_python_builtins(interp: &mut Interpreter) {
325333
.map_err(|e| format!("py_call_kw: pos arg conversion: {}", e))?;
326334
let kwargs = match &kwargs_v {
327335
Value::Dict(d) => {
328-
let py_d = PyDict::new_bound(py);
336+
let py_d = PyDict::new(py);
329337
for (k, v) in d.borrow().iter() {
330338
py_d.set_item(k, omc_to_py(py, v).map_err(|e|
331339
format!("py_call_kw: kwarg {}: {}", k, e))?)
@@ -358,7 +366,7 @@ pub fn register_python_builtins(interp: &mut Interpreter) {
358366
.map_err(|e| format!("py_call_fn_kw: pos arg conversion: {}", e))?;
359367
let kwargs = match &kwargs_v {
360368
Value::Dict(d) => {
361-
let py_d = PyDict::new_bound(py);
369+
let py_d = PyDict::new(py);
362370
for (k, v) in d.borrow().iter() {
363371
py_d.set_item(k, omc_to_py(py, v).map_err(|e|
364372
format!("py_call_fn_kw: kwarg {}: {}", k, e))?)
@@ -385,7 +393,7 @@ pub fn register_python_builtins(interp: &mut Interpreter) {
385393
let cstr = std::ffi::CString::new(code.as_str())
386394
.map_err(|e| format!("py_eval: {}", e))?;
387395
let result = py
388-
.eval_bound(cstr.to_str().unwrap(), None, None)
396+
.eval(cstr.as_c_str(), None, None)
389397
.map_err(|e| format!("py_eval: {}", e))?;
390398
Ok(py_to_omc(py, &result))
391399
})
@@ -399,7 +407,7 @@ pub fn register_python_builtins(interp: &mut Interpreter) {
399407
Python::with_gil(|py| {
400408
let cstr = std::ffi::CString::new(code.as_str())
401409
.map_err(|e| format!("py_exec: {}", e))?;
402-
py.run_bound(cstr.to_str().unwrap(), None, None)
410+
py.run(cstr.as_c_str(), None, None)
403411
.map_err(|e| format!("py_exec: {}", e))?;
404412
Ok(Value::Null)
405413
})
@@ -532,7 +540,7 @@ impl OmcCallback {
532540
pub fn fetch_url(url: &str) -> Result<String, String> {
533541
Python::with_gil(|py| {
534542
let requests = py
535-
.import_bound("requests")
543+
.import("requests")
536544
.map_err(|e| format!("requests not installed: {}", e))?;
537545
let response = requests
538546
.call_method1("get", (url,))
@@ -581,7 +589,7 @@ pub fn install_url_via_python(
581589
/// path is cold (called once per install), so the overhead is fine.
582590
pub fn sha256_hex(bytes: &[u8]) -> String {
583591
Python::with_gil(|py| -> PyResult<String> {
584-
let hashlib = py.import_bound("hashlib")?;
592+
let hashlib = py.import("hashlib")?;
585593
let h = hashlib.call_method1("sha256", (bytes,))?;
586594
let hex = h.call_method0("hexdigest")?;
587595
hex.extract::<String>()
@@ -604,7 +612,7 @@ pub fn registry_lookup(name: &str) -> Result<(String, String), String> {
604612
let body = fetch_url(&registry_url)
605613
.map_err(|e| format!("registry fetch {}: {}", registry_url, e))?;
606614
Python::with_gil(|py| {
607-
let json = py.import_bound("json").map_err(|e| format!("json: {}", e))?;
615+
let json = py.import("json").map_err(|e| format!("json: {}", e))?;
608616
let parsed = json
609617
.call_method1("loads", (body,))
610618
.map_err(|e| format!("registry parse: {}", e))?;
@@ -647,7 +655,7 @@ pub fn registry_lookup(name: &str) -> Result<(String, String), String> {
647655
pub fn parse_omc_toml_via_python(text: &str) -> Result<Vec<(String, String)>, String> {
648656
Python::with_gil(|py| {
649657
let tomllib = py
650-
.import_bound("tomllib")
658+
.import("tomllib")
651659
.map_err(|e| format!("tomllib not available (need Python 3.11+): {}", e))?;
652660
// tomllib.loads(text) — needs bytes in some versions, str in others.
653661
// Use loads with str, fall back to bytes.

omnimcode-core/src/value.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub struct HInt {
1717
}
1818

1919
impl HInt {
20+
#[inline]
2021
pub fn new(value: i64) -> Self {
2122
let resonance = Self::compute_resonance(value);
2223
let him_score = Self::compute_him(value);
@@ -39,6 +40,7 @@ impl HInt {
3940
/// local table covered). For |value| > 610 the new resonance is
4041
/// MORE accurate — the old table saturated at 610, scoring large
4142
/// inputs unfairly low; the new one extends to 63,245,986.
43+
#[inline]
4244
pub fn compute_resonance(value: i64) -> f64 {
4345
let (_nearest, min_dist) = crate::phi_pi_fib::nearest_attractor_with_dist(value);
4446
let abs_val = value.abs();
@@ -50,12 +52,14 @@ impl HInt {
5052
}
5153

5254
/// Compute Harmonic Integer Map (0-1)
55+
#[inline]
5356
pub fn compute_him(value: i64) -> f64 {
5457
let v = value as f64;
5558
let x = (v * PHI) - (v * PHI).floor();
5659
x.abs().min(1.0 - x.abs())
5760
}
5861

62+
#[inline]
5963
pub fn singularity() -> Self {
6064
HInt {
6165
value: 0,
@@ -200,16 +204,19 @@ impl HArray {
200204

201205
/// Construct an HArray from an owned Vec — the most common
202206
/// builder shape (used by literals, splits, range expansion).
207+
#[inline]
203208
pub fn from_vec(v: Vec<Value>) -> Self {
204209
HArray { items: std::rc::Rc::new(std::cell::RefCell::new(v)) }
205210
}
206211

207212
/// Length without taking a guard for the caller. Borrows internally.
213+
#[inline]
208214
pub fn len(&self) -> usize {
209215
self.items.borrow().len()
210216
}
211217

212218
/// True iff the inner vec is empty.
219+
#[inline]
213220
pub fn is_empty(&self) -> bool {
214221
self.items.borrow().is_empty()
215222
}
@@ -273,15 +280,18 @@ pub enum Value {
273280
impl Value {
274281
/// Convenience constructor for a Dict from an owned BTreeMap.
275282
/// Hides the Rc<RefCell<>> wrap from call sites.
283+
#[inline]
276284
pub fn dict_from(m: std::collections::BTreeMap<String, Value>) -> Self {
277285
Value::Dict(std::rc::Rc::new(std::cell::RefCell::new(m)))
278286
}
279287

280288
/// Convenience constructor for an empty Dict.
289+
#[inline]
281290
pub fn dict_empty() -> Self {
282291
Value::dict_from(std::collections::BTreeMap::new())
283292
}
284293

294+
#[inline]
285295
pub fn to_int(&self) -> i64 {
286296
match self {
287297
Value::HInt(h) => h.value,
@@ -294,6 +304,7 @@ impl Value {
294304
}
295305
}
296306

307+
#[inline]
297308
pub fn to_float(&self) -> f64 {
298309
match self {
299310
Value::HInt(h) => h.value as f64,
@@ -306,6 +317,7 @@ impl Value {
306317
}
307318
}
308319

320+
#[inline]
309321
pub fn to_bool(&self) -> bool {
310322
match self {
311323
Value::HInt(h) => h.value != 0,
@@ -395,19 +407,53 @@ impl Value {
395407
}
396408
}
397409

410+
#[inline]
398411
pub fn is_float(&self) -> bool {
399412
matches!(self, Value::HFloat(_))
400413
}
401414

415+
#[inline]
402416
pub fn is_numeric(&self) -> bool {
403417
matches!(self, Value::HInt(_) | Value::HFloat(_))
404418
}
405419

420+
#[inline]
406421
pub fn is_singularity(&self) -> bool {
407422
matches!(self, Value::Singularity { .. })
408423
// Backward compat: HInt with the old flag set still counts.
409424
|| matches!(self, Value::HInt(h) if h.is_singularity)
410425
}
426+
427+
/// Quickly distinguish a Value::HInt without binding/destructuring.
428+
/// Hot in dispatch paths that pre-check before extracting.
429+
#[inline]
430+
pub fn is_int(&self) -> bool {
431+
matches!(self, Value::HInt(_))
432+
}
433+
434+
/// Quickly distinguish a Value::String without allocating.
435+
#[inline]
436+
pub fn is_string(&self) -> bool {
437+
matches!(self, Value::String(_))
438+
}
439+
440+
/// Quickly distinguish a Value::Array without borrowing.
441+
#[inline]
442+
pub fn is_array(&self) -> bool {
443+
matches!(self, Value::Array(_))
444+
}
445+
446+
/// Quickly distinguish a Value::Dict without borrowing.
447+
#[inline]
448+
pub fn is_dict(&self) -> bool {
449+
matches!(self, Value::Dict(_))
450+
}
451+
452+
/// Quickly distinguish Value::Null without going through to_bool.
453+
#[inline]
454+
pub fn is_null(&self) -> bool {
455+
matches!(self, Value::Null)
456+
}
411457
}
412458

413459
impl fmt::Display for Value {

0 commit comments

Comments
 (0)