mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
- Implement `getModerationInfoForAuthors` in `ModerationService` for batching. - Extract utility functions to `js/services/moderationUtils.js` to reduce `ModerationService` size. - Update `createModerationStage` to use batch lookup, reducing sequential overhead. - Benchmarks show ~50% improvement (454ms -> 227ms) for 5000 items. - All unit tests pass. - Task log: `docs/agents/task-logs/weekly/2026-02-22_01-25-01_perf-optimization-agent_completed.md` Co-authored-by: PR0M3TH3AN <[email protected]>
122 lines
2.9 KiB
JavaScript
122 lines
2.9 KiB
JavaScript
|
|
// Mock Globals BEFORE imports
|
|
global.localStorage = {
|
|
getItem: () => null,
|
|
setItem: () => {},
|
|
removeItem: () => {},
|
|
clear: () => {}
|
|
};
|
|
global.window = { localStorage: global.localStorage };
|
|
|
|
// Dynamic imports to ensure globals are set first
|
|
const { ModerationService } = await import('../js/services/moderationService.js');
|
|
const { createModerationStage } = await import('../js/feedEngine/stages.js');
|
|
const { performance } = await import('node:perf_hooks');
|
|
|
|
// Mock Dependencies
|
|
const mockClient = {
|
|
pool: {},
|
|
ensurePool: async () => {},
|
|
pubkey: 'viewer-pubkey',
|
|
};
|
|
|
|
const mockLogger = {
|
|
log: () => {},
|
|
dev: { log: () => {}, debug: () => {} },
|
|
user: { warn: () => {}, info: () => {} }
|
|
};
|
|
|
|
const service = new ModerationService({
|
|
nostrClient: mockClient,
|
|
logger: mockLogger,
|
|
});
|
|
|
|
// Helper to generate valid hex
|
|
function makeHex(prefix, index) {
|
|
return `${prefix}${index.toString(16).padStart(64 - prefix.length, '0')}`;
|
|
}
|
|
|
|
// Setup Data
|
|
const AUTHOR_COUNT = 500;
|
|
const MUTERS_PER_AUTHOR = 100;
|
|
const now = Date.now() / 1000;
|
|
|
|
console.log(`Populating ${AUTHOR_COUNT} authors with ${MUTERS_PER_AUTHOR} muters each...`);
|
|
|
|
for (let i = 0; i < AUTHOR_COUNT; i++) {
|
|
const author = makeHex('abc', i);
|
|
const muters = new Map();
|
|
const categories = new Map();
|
|
|
|
for (let j = 0; j < MUTERS_PER_AUTHOR; j++) {
|
|
const muter = makeHex('def', j);
|
|
muters.set(muter, now); // Not expired
|
|
}
|
|
|
|
// Add some categories
|
|
const catMuters = new Map();
|
|
const firstMuter = makeHex('def', 0);
|
|
catMuters.set(firstMuter, now);
|
|
categories.set('spam', catMuters);
|
|
|
|
// We manually inject into internal map to bypass setter logic
|
|
service.trustedMutedAuthors.set(author, {
|
|
muters,
|
|
categories,
|
|
count: muters.size,
|
|
lastPrunedAt: 0 // Force prune check
|
|
});
|
|
}
|
|
|
|
// Prepare items for stage
|
|
const ITEM_COUNT = 5000;
|
|
const items = [];
|
|
for (let i = 0; i < ITEM_COUNT; i++) {
|
|
const authorIndex = i % AUTHOR_COUNT;
|
|
const author = makeHex('abc', authorIndex);
|
|
items.push({
|
|
video: {
|
|
id: makeHex('123', i),
|
|
pubkey: author,
|
|
kind: 30078,
|
|
moderation: {}
|
|
},
|
|
metadata: {}
|
|
});
|
|
}
|
|
|
|
const context = {
|
|
runtime: {
|
|
moderationThresholds: {
|
|
autoplayBlockThreshold: 1,
|
|
blurThreshold: 1,
|
|
trustedSpamHideThreshold: 1,
|
|
trustedMuteHideThresholds: {}
|
|
},
|
|
isAuthorBlocked: () => false
|
|
},
|
|
log: () => {},
|
|
addWhy: () => {}
|
|
};
|
|
|
|
async function runBenchmark() {
|
|
console.log('Running Moderation Stage Benchmark (Sequential Lookups)...');
|
|
|
|
const moderationStage = createModerationStage({
|
|
service: service,
|
|
stageName: 'bench-moderation-sequential'
|
|
});
|
|
|
|
// Warmup
|
|
await moderationStage(items.slice(0, 100), context);
|
|
|
|
// Measure
|
|
const start = performance.now();
|
|
await moderationStage(items, context);
|
|
const end = performance.now();
|
|
|
|
console.log(`Time: ${(end - start).toFixed(2)}ms`);
|
|
}
|
|
|
|
runBenchmark().catch(console.error);
|