test: add FBIP and RC verification test cases
Add test cases demonstrating FBIP (Functional But In-Place) optimization: - test_fbip_clean.lux: Basic FBIP chain (map, filter, reverse) - test_fbip_allocs.lux: Single-owner allocation test with range/map/filter/reverse - test_no_fbip.lux: Demonstrates shared reference forcing rc>1 path - test_rc_comparison.lux: Comparison of FBIP vs non-FBIP allocations All tests verify no memory leaks with the RC system. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
17
examples/test_fbip_allocs.lux
Normal file
17
examples/test_fbip_allocs.lux
Normal file
@@ -0,0 +1,17 @@
|
||||
// This test shows FBIP optimization by comparing allocation counts
|
||||
// With FBIP (rc=1): lists are reused in-place
|
||||
// Without FBIP (rc>1): new lists are allocated
|
||||
|
||||
fn main(): Unit = {
|
||||
Console.print("=== FBIP Allocation Test ===")
|
||||
|
||||
// Case 1: Single owner (FBIP active) - should reuse list
|
||||
let a = List.range(1, 100)
|
||||
let b = List.map(a, fn(x: Int): Int => x * 2)
|
||||
let c = List.filter(b, fn(x: Int): Bool => x > 50)
|
||||
let d = List.reverse(c)
|
||||
Console.print("Single owner chain done")
|
||||
|
||||
// The allocation count will show FBIP is working
|
||||
// if allocations are low relative to operations performed
|
||||
}
|
||||
9
examples/test_fbip_clean.lux
Normal file
9
examples/test_fbip_clean.lux
Normal file
@@ -0,0 +1,9 @@
|
||||
fn main(): Unit = {
|
||||
// Test FBIP without string operations
|
||||
let nums = [1, 2, 3, 4, 5]
|
||||
let doubled = List.map(nums, fn(x: Int): Int => x * 2)
|
||||
let filtered = List.filter(doubled, fn(x: Int): Bool => x > 4)
|
||||
let reversed = List.reverse(filtered)
|
||||
let len = List.length(reversed)
|
||||
Console.print("done")
|
||||
}
|
||||
20
examples/test_no_fbip.lux
Normal file
20
examples/test_no_fbip.lux
Normal file
@@ -0,0 +1,20 @@
|
||||
// Test WITHOUT FBIP by forcing rc>1 (shared reference)
|
||||
fn useList(l: List<Int>): Int = {
|
||||
List.length(l)
|
||||
}
|
||||
|
||||
fn main(): Unit = {
|
||||
Console.print("=== Without FBIP (forced rc>1) ===")
|
||||
|
||||
let a = List.range(1, 100)
|
||||
// Create alias to bump rc, preventing FBIP
|
||||
let alias = a
|
||||
let len1 = useList(alias)
|
||||
|
||||
// Now 'a' has rc>1 so map must allocate new list
|
||||
let b = List.map(a, fn(x: Int): Int => x * 2)
|
||||
let c = List.filter(b, fn(x: Int): Bool => x > 50)
|
||||
let d = List.reverse(c)
|
||||
|
||||
Console.print("Shared reference chain done")
|
||||
}
|
||||
17
examples/test_rc_comparison.lux
Normal file
17
examples/test_rc_comparison.lux
Normal file
@@ -0,0 +1,17 @@
|
||||
fn main(): Unit = {
|
||||
Console.print("=== Allocation Comparison ===")
|
||||
|
||||
// FBIP path (rc=1): list is reused
|
||||
Console.print("Test 1: FBIP path")
|
||||
let a1 = List.range(1, 50)
|
||||
let b1 = List.map(a1, fn(x: Int): Int => x * 2)
|
||||
let c1 = List.reverse(b1)
|
||||
Console.print("FBIP done")
|
||||
|
||||
// To show non-FBIP, we need concat which doesn't have FBIP
|
||||
Console.print("Test 2: Non-FBIP path (concat)")
|
||||
let x = List.range(1, 25)
|
||||
let y = List.range(26, 50)
|
||||
let z = List.concat(x, y) // concat always allocates new
|
||||
Console.print("Concat done")
|
||||
}
|
||||
Reference in New Issue
Block a user