增加一个不使用array方法的方案进行对比。

This commit is contained in:
a92126 2024-10-15 13:08:33 +08:00
parent 5ebede3a4e
commit 15694de28c
3 changed files with 237 additions and 67 deletions

View File

@ -1,10 +1,25 @@
const { readFile, writeFile } = require("fs/promises");
const transform = require("./worker");
const fastly = process.env.OAFCHT_NO_ITER==='1';
const loadlist = async () => {
const datfile = await readFile("./serial.json");
const datas = JSON.parse(datfile.toString());
// 避免使用迭代器方法减少CPU已走过performance对比流程
// ---------------原来的代码在这里------------------
if( fastly === false ){
return Object.entries(datas).filter(n => n[1] != "????");
}
// ---------------修改的代码在这里------------------
const entries = Object.entries(datas);
const retval = new Array(entries.length);
let l = 0;
for( const data of entries ){
if( data[1] !== "????" ) retval[l++] = data;
}
retval.length = l;
return retval;
// ---------------修改的代码完结处------------------
}
const format = valid => {
@ -32,9 +47,10 @@ const format = valid => {
return a;
}
}
const getnametable = list => list.reduce((r, { serial, cheat }, idx, arr) => {
// 避免使用迭代器方法减少CPU已走过performance对比流程
// ---------------原来的代码在这里------------------
const getnametable = fastly === false ? list => list.reduce((r, { serial, cheat }, idx, arr) => {
const val = serial.slice(0, -1);
//console.log("looping", val, r[4], r[2], cheat.length)
const size1 = size.get(r[1]);
if (val != r[4]) {
if (size1 > 0 && r[2] - r[1].at(size1 - 1) > r[3])
@ -50,9 +66,37 @@ const format = valid => {
r[1] = concat(r[1], [r[2]]);
}
return r;
}, [concat(new Uint8Array(concatUnit), []), concat(new Uint16Array(concatUnit), []), 0, 0, ""]);
}, [concat(new Uint8Array(concatUnit), []), concat(new Uint16Array(concatUnit), []), 0, 0, ""])
// ---------------修改的代码在这里------------------
: list => {
const ret = [concat(new Uint8Array(concatUnit), []), concat(new Uint16Array(concatUnit), []), 0, 0, ""];
const {length} = list;
for( let idx=0; idx < length; ++idx ){
const { serial, cheat } = list[idx];
const val = serial.slice(0, -1);
const size1 = size.get(ret[1]);
if( val != ret[4] ){
if( size1 > 0 && ret[2] - ret[1].at(size1 - 1) > ret[3] )
ret[3] = ret[2] - ret[1].at(size1 - 1);
ret[0] = concat(ret[0], enc.encode(val))
ret[1] = concat(ret[1], [ret[2]]);
ret[4] = val;
}
ret[2] = ret[2] + cheat.length;
if( idx + 1 == length ){
if( ret[2] - ret[1].at(size1 - 1) > ret[3] )
ret[3] = ret[2] - ret[1].at(size1 - 1);
ret[1] = concat(ret[1], [ret[2]]);
}
}
return ret;
};
// ---------------修改的代码完结处------------------
const expandcheat = (list, base) => list.reduce((r, { cheat, serial }) => {
// 避免使用迭代器方法减少CPU已走过performance对比流程
// ---------------原来的代码在这里------------------
const expandcheat = fastly === false ? (list, base) => list.reduce((r, { cheat, serial }) => {
const val = serial.charCodeAt(3);
return cheat.reduce((r, { id, bin }) => {
const off = r[2] + size.get(r[1]);
@ -60,7 +104,23 @@ const format = valid => {
r[1] = concat(r[1], bin);
return r;
}, r);
}, [concat(new Uint32Array(concatUnit), []), concat(new Uint8Array(concatUnit), []), align(base, 32)]);
}, [concat(new Uint32Array(concatUnit), []), concat(new Uint8Array(concatUnit), []), align(base, 32)])
// ---------------修改的代码在这里------------------
: (list, base) => {
const ret = [concat(new Uint32Array(concatUnit), []), concat(new Uint8Array(concatUnit), []), align(base, 32)];
const {length} = list;
for( let idx=0; idx < length; ++idx ){
const { cheat, serial } = list[idx];
const val = serial.charCodeAt(3);
for( const { id, bin } of cheat ){
const off = ret[2] + size.get(ret[1]);
ret[0] = concat(ret[0], [val | (off << 3), id])
ret[1] = concat(ret[1], bin);
}
}
return ret;
};
// ---------------修改的代码完结处------------------
const linkbuffer = (arr, ...l) => {
for (let i of l) {
@ -106,6 +166,9 @@ const start = async () => {
let list = await loadlist();
let roms = await transform(list);
console.log(`all rom has ${roms.length} and time ${performance.now() - begin}`);
// 避免使用迭代器方法减少CPU已走过performance对比流程
// ---------------原来的代码在这里------------------
if( fastly === false ){
roms = Object.entries(roms.reduce((r, data) => {
if (!data) return r;
@ -115,6 +178,29 @@ const start = async () => {
else r[serial] = cheat;
return r;
}, {})).map(([serial, cheat]) => ({ serial, cheat }));
}
// ---------------修改的代码在这里------------------
else
{
const res = new Array(10240), idx = {};
let l = 0;
for( const data of roms ){
if( !data ) continue;
const { serial, cheat } = data;
if( !cheat || cheat.length == 0 ) continue;
const cheats = idx[serial] ? idx[serial] : [];
cheats.push(...cheat);
if( !idx[serial] ){
idx[serial] = cheats;
res[l++] = { serial, cheat: cheats };
}
}
res.length = l;
roms = res;
}
// ---------------修改的代码完结处------------------
const content = await format( roms );
await writeFile( "gba.acl", content );

View File

@ -18,7 +18,8 @@ const nine = "9".charCodeAt();
const a = "a".charCodeAt();
const f = "f".charCodeAt();
const conv = new TextEncoder();
const fastly = process.env.OAFCHT_NO_REUSE==='1';
const noiter = process.env.OAFCHT_NO_ITER==='1';
const noreuse = process.env.OAFCHT_NO_REUSE==='1';
/**
* 这个函数做了一些数据复用处理能省下来一点文件容量
@ -224,15 +225,33 @@ const assembleCheat = (list, dup, hole) => {
else if (0 == (n & 0xf000000)) return (n & 0xffff) | 0x3000000;
else return n;
};
const addrval = list.reduce((r, command) => {
// 避免使用迭代器方法减少CPU已走过performance对比流程
// ---------------原来的代码在这里------------------
const addrval = new Map();
if( noiter === false ){
list.forEach((command) => {
let addr = fromTaddr(command[0]);
let len = command.length - 1;
for( let pos=0; pos < len; ++pos) {
r.set(addr+pos, parseInt(command[pos+1], 16))
addrval.set(addr+pos, parseInt(command[pos+1], 16))
}
return r;
}, new Map());
});
}
// ---------------修改的代码在这里------------------
else {
for( const command of list ){
const addr = fromTaddr(command[0]);
const len = command.length - 1;
for( let pos=0; pos < len; ++pos) {
addrval.set(addr+pos, parseInt(command[pos+1], 16));
}
}
}
// ---------------修改的代码完结处------------------
const ordered = Array.from(addrval).sort((a, b) => a[0] - b[0]);
// 避免使用迭代器方法减少CPU已走过performance对比流程
// ---------------原来的代码在这里------------------
if( noiter === false ){
const blocks = ordered.reduce((arr, [addr, value]) => {
dup.set(addr, hole);
if (arr.length == 0) {
@ -240,7 +259,7 @@ const assembleCheat = (list, dup, hole) => {
}
else {
let cur = arr.at(-1);
if (cur.value == value) {
if (cur.value == value && cur.addr + cur.count == addr) {
++cur.count;
}
else arr.push({ addr, value, count: 1 });
@ -251,7 +270,31 @@ const assembleCheat = (list, dup, hole) => {
r.push( block.addr );
r.push( (block.count << 8) | block.value )
return r;
}, []))
}, []));
}
// ---------------修改的代码在这里------------------
else {
const blocks = new Array();
let curr = null;
for( const [addr, value] of ordered ){
dup.set(addr, hole);
if( !curr ) {
curr = { addr, value, count: 1 };
}
else {
if( curr.value == value && curr.addr + curr.count == addr ) {
++curr.count;
}
else {
blocks.push( curr.addr, (curr.count << 8) | curr.value );
curr = { addr, value, count: 1 };
}
}
}
if( curr ) blocks.push( curr.addr, (curr.count << 8) | curr.value );
return Uint32Array.from(blocks);
}
// ---------------修改的代码完结处------------------
}
const pack = (entlist, strlist, idxlist, cmdlist, xvalue) => {
@ -338,7 +381,7 @@ const lade = (list, info, order) => {
size.str = len;
return off;
};
const ut_addtr = fastly ? (() => {
const ut_addtr = noreuse ? (() => {
const cache = {};
return tr => {// 不要直接ut_pushtr因为有些秘籍会撑爆字符串表
if (cache[tr] != undefined) return cache[tr];
@ -354,8 +397,21 @@ const lade = (list, info, order) => {
const off = findIndex(strtable, code, size.str);
return off < 0 ? ut_pushtr(code) : off;
};
// 避免使用迭代器方法减少CPU已走过performance对比流程
// ---------------原来的代码在这里------------------
if( noiter === false ){
return list.map(ut_addtr);
}
// ---------------修改的代码在这里------------------
else {
let res = new Array(list.length);
for( let i=0; i < list.length; ++i ){
res[i] = ut_addtr(list[i]);
}
return res;
}
// ---------------修改的代码完结处------------------
}
const addStrIndex = list => {
if (list.length == 0) return 0;
@ -400,7 +456,11 @@ const lade = (list, info, order) => {
// pack
let holedup = new Map();
let entbytelist = enttable.map(entry => {
// 避免使用迭代器方法减少CPU已走过performance对比流程
// ---------------原来的代码在这里------------------
let entbytelist;
if( noiter === false ){
entbytelist = enttable.map(entry => {
let { id, data } = entry;
if (id < 0x10000) { // 收集str
let idxlist = id == 0 ? addString( data ) : addString(data.length > 1 ? data : []); // length==1就是开启
@ -413,6 +473,25 @@ const lade = (list, info, order) => {
return Uint32Array.of(id, location, armbytecode.length);
}
});
}
// ---------------修改的代码在这里------------------
else {
entbytelist = new Array(enttable.length);
for( let i=0; i < enttable.length; i++ ){
let { id, data } = enttable[i];
if (id < 0x10000) {
let idxlist = id == 0 ? addString( data ) : addString(data.length > 1 ? data : []); // length==1就是开启
let location = addStrIndex(idxlist);
entbytelist[i] = Uint32Array.of(id, location, idxlist.length);
}
else {
let armbytecode = assembleCheat(data, holedup, id & 0xffff);
let location = addCommand(armbytecode);
entbytelist[i] = Uint32Array.of(id, location, armbytecode.length);
}
}
}
// ---------------修改的代码完结处------------------
cmdtable = cmdtable.slice(0, size.cmd);
strtable = strtable.slice(0, size.str);
idxtable = idxtable.slice(0, size.idx);

View File

@ -3,6 +3,21 @@ const {Worker, isMainThread, parentPort, workerData} = require("worker_threads")
const readCht = require("./cht");
const { readFileSync } = require("fs");
const ncpu = require("os").availableParallelism();
const fastly = process.env.OAFCHT_NO_ITER==='1';
const handlelist = fastly === false ? list => list.map( game => {
const [order, serial, title] = game;
const file = `./gba/${order}.u8`;
return loadcheat(order, serial, title ?? order, file);
}) : list => {
const res = new Array(list.length);
for( let i=0; i < list.length; i++ ) {
const [order, serial, title] = list[i];
const file = `./gba/${order}.u8`;
res[i] = loadcheat(order, serial, title ?? order, file) ;
}
return res;
};
const loadcheat = (order, serial, title, file) => {
try {
@ -32,11 +47,7 @@ if( isMainThread ) {
});
} );
});
} : list => Promise.resolve( list.map( game => {
const [order, serial, title] = game;
const file = `./gba/${order}.u8`;
return loadcheat(order, serial, title ?? order, file);
} ) );
} : list => Promise.resolve( handlelist(list) );
}
else {
const list = workerData;
@ -45,11 +56,5 @@ else {
const file = `./gba/${order}.u8`;
return loadcheat(order, serial, title ?? order, file);
} ) ).then( res => parentPort.postMessage(res) );*/
parentPort.postMessage(
list.map( game => {
const [order, serial, title] = game;
const file = `./gba/${order}.u8`;
return loadcheat(order, serial, title ?? order, file);
})
);
parentPort.postMessage( handlelist(list) );
}