@@ -1172,6 +1172,265 @@ Deno.bench({
11721172 } ,
11731173} ) ;
11741174
1175+ // =============================================================================
1176+ // ZERO-ALLOCATION MODE BENCHMARKS
1177+ // =============================================================================
1178+
1179+ Deno . bench ( {
1180+ name : "SparseFacade - Map-based mode (arbitrary entity IDs)" ,
1181+ fn : ( ) => {
1182+ const buffer = new PartitionedBuffer ( 1024 , 64 ) ;
1183+ type Schema = { value : number } ;
1184+ // Map-based: no maxEntityId specified
1185+ const spec : PartitionSpec < Schema > = {
1186+ name : "mapBased" ,
1187+ schema : { value : Float32Array } ,
1188+ maxOwners : 16 ,
1189+ } ;
1190+ const partition = buffer . addPartition ( new Partition ( spec ) ) ;
1191+ if ( ! partition ) return ;
1192+
1193+ // Simulate entity operations with arbitrary IDs
1194+ for ( let i = 0 ; i < 16 ; i ++ ) {
1195+ partition . partitions . value [ i * 1000 ] = i * 1.5 ; // Large entity IDs
1196+ }
1197+ for ( let i = 0 ; i < 16 ; i ++ ) {
1198+ partition . partitions . value [ i * 1000 ] ; // Read
1199+ }
1200+ for ( let i = 0 ; i < 8 ; i ++ ) {
1201+ delete partition . partitions . value [ i * 1000 ] ; // Delete half
1202+ }
1203+ } ,
1204+ } ) ;
1205+
1206+ Deno . bench ( {
1207+ name : "SparseFacade - Zero-allocation mode (bounded entity IDs)" ,
1208+ fn : ( ) => {
1209+ const buffer = new PartitionedBuffer ( 1024 , 64 ) ;
1210+ type Schema = { value : number } ;
1211+ // Zero-allocation: maxEntityId specified
1212+ const spec : PartitionSpec < Schema > & { maxEntityId : number } = {
1213+ name : "zeroAlloc" ,
1214+ schema : { value : Float32Array } ,
1215+ maxOwners : 16 ,
1216+ maxEntityId : 20000 , // Pre-allocated sparse array
1217+ } ;
1218+ const partition = buffer . addPartition ( new Partition ( spec ) ) ;
1219+ if ( ! partition ) return ;
1220+
1221+ // Same operations as Map-based for fair comparison
1222+ for ( let i = 0 ; i < 16 ; i ++ ) {
1223+ partition . partitions . value [ i * 1000 ] = i * 1.5 ;
1224+ }
1225+ for ( let i = 0 ; i < 16 ; i ++ ) {
1226+ partition . partitions . value [ i * 1000 ] ;
1227+ }
1228+ for ( let i = 0 ; i < 8 ; i ++ ) {
1229+ delete partition . partitions . value [ i * 1000 ] ;
1230+ }
1231+ } ,
1232+ } ) ;
1233+
1234+ Deno . bench ( {
1235+ name : "SparseFacade - Zero-allocation high-frequency write" ,
1236+ fn : ( ) => {
1237+ const buffer = new PartitionedBuffer ( 2048 , 128 ) ;
1238+ type Schema = { x : number ; y : number } ;
1239+ const spec : PartitionSpec < Schema > & { maxEntityId : number } = {
1240+ name : "zeroAllocFrequent" ,
1241+ schema : { x : Float32Array , y : Float32Array } ,
1242+ maxOwners : 32 ,
1243+ maxEntityId : 10000 ,
1244+ } ;
1245+ const partition = buffer . addPartition ( new Partition ( spec ) ) ;
1246+ if ( ! partition ) return ;
1247+
1248+ // High-frequency updates (typical game loop pattern)
1249+ for ( let frame = 0 ; frame < 10 ; frame ++ ) {
1250+ for ( let entity = 0 ; entity < 32 ; entity ++ ) {
1251+ const entityId = entity * 100 ;
1252+ partition . partitions . x [ entityId ] = Math . sin ( frame + entity ) ;
1253+ partition . partitions . y [ entityId ] = Math . cos ( frame + entity ) ;
1254+ }
1255+ }
1256+ } ,
1257+ } ) ;
1258+
1259+ Deno . bench ( {
1260+ name : "SparseFacade - Map-based high-frequency write" ,
1261+ fn : ( ) => {
1262+ const buffer = new PartitionedBuffer ( 2048 , 128 ) ;
1263+ type Schema = { x : number ; y : number } ;
1264+ const spec : PartitionSpec < Schema > = {
1265+ name : "mapBasedFrequent" ,
1266+ schema : { x : Float32Array , y : Float32Array } ,
1267+ maxOwners : 32 ,
1268+ // No maxEntityId - uses Map
1269+ } ;
1270+ const partition = buffer . addPartition ( new Partition ( spec ) ) ;
1271+ if ( ! partition ) return ;
1272+
1273+ // Same pattern for comparison
1274+ for ( let frame = 0 ; frame < 10 ; frame ++ ) {
1275+ for ( let entity = 0 ; entity < 32 ; entity ++ ) {
1276+ const entityId = entity * 100 ;
1277+ partition . partitions . x [ entityId ] = Math . sin ( frame + entity ) ;
1278+ partition . partitions . y [ entityId ] = Math . cos ( frame + entity ) ;
1279+ }
1280+ }
1281+ } ,
1282+ } ) ;
1283+
1284+ Deno . bench ( {
1285+ name : "SparseFacade - Zero-allocation entity churn" ,
1286+ fn : ( ) => {
1287+ const buffer = new PartitionedBuffer ( 1024 , 64 ) ;
1288+ type Schema = { value : number } ;
1289+ const spec : PartitionSpec < Schema > & { maxEntityId : number } = {
1290+ name : "churnZeroAlloc" ,
1291+ schema : { value : Int32Array } ,
1292+ maxOwners : 8 ,
1293+ maxEntityId : 1000 ,
1294+ } ;
1295+ const partition = buffer . addPartition ( new Partition ( spec ) ) ;
1296+ if ( ! partition ) return ;
1297+
1298+ // Simulate entity creation/destruction churn
1299+ for ( let cycle = 0 ; cycle < 5 ; cycle ++ ) {
1300+ // Create entities
1301+ for ( let i = 0 ; i < 8 ; i ++ ) {
1302+ partition . partitions . value [ cycle * 100 + i ] = i ;
1303+ }
1304+ // Destroy entities
1305+ for ( let i = 0 ; i < 8 ; i ++ ) {
1306+ delete partition . partitions . value [ cycle * 100 + i ] ;
1307+ }
1308+ }
1309+ } ,
1310+ } ) ;
1311+
1312+ Deno . bench ( {
1313+ name : "SparseFacade - Map-based entity churn" ,
1314+ fn : ( ) => {
1315+ const buffer = new PartitionedBuffer ( 1024 , 64 ) ;
1316+ type Schema = { value : number } ;
1317+ const spec : PartitionSpec < Schema > = {
1318+ name : "churnMapBased" ,
1319+ schema : { value : Int32Array } ,
1320+ maxOwners : 8 ,
1321+ // No maxEntityId
1322+ } ;
1323+ const partition = buffer . addPartition ( new Partition ( spec ) ) ;
1324+ if ( ! partition ) return ;
1325+
1326+ // Same churn pattern
1327+ for ( let cycle = 0 ; cycle < 5 ; cycle ++ ) {
1328+ for ( let i = 0 ; i < 8 ; i ++ ) {
1329+ partition . partitions . value [ cycle * 100 + i ] = i ;
1330+ }
1331+ for ( let i = 0 ; i < 8 ; i ++ ) {
1332+ delete partition . partitions . value [ cycle * 100 + i ] ;
1333+ }
1334+ }
1335+ } ,
1336+ } ) ;
1337+
1338+ Deno . bench ( {
1339+ name : "SparseFacade - Zero-allocation read-heavy workload" ,
1340+ fn : ( ) => {
1341+ const buffer = new PartitionedBuffer ( 1024 , 64 ) ;
1342+ type Schema = { value : number } ;
1343+ const spec : PartitionSpec < Schema > & { maxEntityId : number } = {
1344+ name : "readHeavyZeroAlloc" ,
1345+ schema : { value : Float32Array } ,
1346+ maxOwners : 16 ,
1347+ maxEntityId : 2000 ,
1348+ } ;
1349+ const partition = buffer . addPartition ( new Partition ( spec ) ) ;
1350+ if ( ! partition ) return ;
1351+
1352+ // Setup
1353+ for ( let i = 0 ; i < 16 ; i ++ ) {
1354+ partition . partitions . value [ i * 100 ] = i ;
1355+ }
1356+
1357+ // Heavy reads (common in render systems)
1358+ let sum = 0 ;
1359+ for ( let frame = 0 ; frame < 100 ; frame ++ ) {
1360+ for ( let i = 0 ; i < 16 ; i ++ ) {
1361+ sum += partition . partitions . value [ i * 100 ] ?? 0 ;
1362+ }
1363+ }
1364+ } ,
1365+ } ) ;
1366+
1367+ Deno . bench ( {
1368+ name : "SparseFacade - Map-based read-heavy workload" ,
1369+ fn : ( ) => {
1370+ const buffer = new PartitionedBuffer ( 1024 , 64 ) ;
1371+ type Schema = { value : number } ;
1372+ const spec : PartitionSpec < Schema > = {
1373+ name : "readHeavyMapBased" ,
1374+ schema : { value : Float32Array } ,
1375+ maxOwners : 16 ,
1376+ } ;
1377+ const partition = buffer . addPartition ( new Partition ( spec ) ) ;
1378+ if ( ! partition ) return ;
1379+
1380+ // Setup
1381+ for ( let i = 0 ; i < 16 ; i ++ ) {
1382+ partition . partitions . value [ i * 100 ] = i ;
1383+ }
1384+
1385+ // Heavy reads
1386+ let sum = 0 ;
1387+ for ( let frame = 0 ; frame < 100 ; frame ++ ) {
1388+ for ( let i = 0 ; i < 16 ; i ++ ) {
1389+ sum += partition . partitions . value [ i * 100 ] ?? 0 ;
1390+ }
1391+ }
1392+ } ,
1393+ } ) ;
1394+
1395+ Deno . bench ( {
1396+ name : "SparseFacade - Zero-allocation multi-component ECS pattern" ,
1397+ fn : ( ) => {
1398+ const buffer = new PartitionedBuffer ( 4096 , 256 ) ;
1399+ const maxEntityId = 10000 ;
1400+
1401+ // Typical ECS components with zero-allocation
1402+ type PosSchema = { x : number ; y : number ; z : number } ;
1403+ const posSpec : PartitionSpec < PosSchema > & { maxEntityId : number } = {
1404+ name : "position" ,
1405+ schema : { x : Float32Array , y : Float32Array , z : Float32Array } ,
1406+ maxOwners : 64 ,
1407+ maxEntityId,
1408+ } ;
1409+
1410+ type VelSchema = { x : number ; y : number ; z : number } ;
1411+ const velSpec : PartitionSpec < VelSchema > & { maxEntityId : number } = {
1412+ name : "velocity" ,
1413+ schema : { x : Float32Array , y : Float32Array , z : Float32Array } ,
1414+ maxOwners : 64 ,
1415+ maxEntityId,
1416+ } ;
1417+
1418+ const pos = buffer . addPartition ( new Partition ( posSpec ) ) ;
1419+ const vel = buffer . addPartition ( new Partition ( velSpec ) ) ;
1420+ if ( ! pos || ! vel ) return ;
1421+
1422+ // Physics update simulation
1423+ for ( let frame = 0 ; frame < 10 ; frame ++ ) {
1424+ for ( let entity = 0 ; entity < 64 ; entity ++ ) {
1425+ const id = entity * 100 ;
1426+ pos . partitions . x [ id ] ! += vel . partitions . x ?. [ id ] ?? 0 ;
1427+ pos . partitions . y [ id ] ! += vel . partitions . y ?. [ id ] ?? 0 ;
1428+ pos . partitions . z [ id ] ! += vel . partitions . z ?. [ id ] ?? 0 ;
1429+ }
1430+ }
1431+ } ,
1432+ } ) ;
1433+
11751434Deno . bench ( {
11761435 name : "PartitionedBuffer - Memory pressure scenario" ,
11771436 fn : ( ) => {
0 commit comments