Files
cloud-orchestrator/scripts/parse-benchmarks.ts
kappa 4cb9da06dc feat: 대역폭 추정 및 DAU 표시 기능 추가
- 동시접속자 기반 월간 대역폭 자동 추정
- DAU(일일활성사용자) 추정치 표시 (동접 × 10-14)
- 대역폭 기반 Linode/Vultr 자동 선택 로직
- 비용 분석에 대역폭 비용 포함
- 지역 미선택시 서울/도쿄/오사카/싱가포르 기본 표시
- 지역별 서버 분리 표시 (GROUP BY instance + region)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:40:36 +09:00

171 lines
4.8 KiB
TypeScript

import * as fs from 'fs';
import * as path from 'path';
interface BenchmarkRow {
idproc: string;
descproc: string;
percentile: string;
nbproc: string;
perf: string;
}
const BENCHMARK_FILES = [
'pts-nginx.csv',
'pts-apache.csv',
'pts-apache-siege.csv',
'pts-node-octane.csv',
'pts-node-express-loadtest.csv',
'pts-phpbench.csv',
'pts-redis.csv',
'pts-mysqlslap.csv',
'pts-compress-7zip.csv',
'pts-compress-pbzip2.csv',
'pts-compress-gzip.csv',
'pts-postmark.csv',
'pts-compilebench.csv',
'pts-c-ray.csv',
'pts-coremark.csv',
'pts-byte.csv',
'pts-encode-mp3.csv',
'pts-encode-flac.csv',
'pts-x264.csv',
'pts-build-imagemagick.csv',
'pts-build-nodejs.csv',
'pts-build-php.csv',
];
function parseCSV(content: string): BenchmarkRow[] {
const lines = content.trim().split('\n');
const header = lines[0].split(',');
const rows: BenchmarkRow[] = [];
for (let i = 1; i < lines.length; i++) {
const values = lines[i].split(',');
if (values.length >= 6) {
rows.push({
idproc: values[1],
descproc: values[2],
percentile: values[3],
nbproc: values[4],
perf: values[5],
});
}
}
return rows;
}
function parsePerf(perf: string): { score: number; deviation: number | null } {
// Format: "496096 +/- 4671" or "496096"
const match = perf.match(/^([\d.]+)\s*(?:\+\/-\s*([\d.]+))?$/);
if (match) {
return {
score: parseFloat(match[1]),
deviation: match[2] ? parseFloat(match[2]) : null,
};
}
return { score: 0, deviation: null };
}
function parsePercentile(percentile: string): number {
// Format: "100th", "98th", "95th", etc.
const match = percentile.match(/^(\d+)/);
return match ? parseInt(match[1]) : 0;
}
function extractVendor(name: string): string {
if (name.toLowerCase().includes('amd')) return 'AMD';
if (name.toLowerCase().includes('intel')) return 'Intel';
if (name.toLowerCase().includes('arm')) return 'ARM';
if (name.toLowerCase().includes('apple')) return 'Apple';
return 'Unknown';
}
function extractCores(name: string): number | null {
// Try to extract core count from name
const match = name.match(/(\d+)-Core/i);
return match ? parseInt(match[1]) : null;
}
function escapeSQL(str: string): string {
return str.replace(/'/g, "''");
}
async function main() {
const dataDir = path.join(__dirname, '../benchmark-data/data/suite');
const processors = new Map<string, { name: string; vendor: string; cores: number | null }>();
const benchmarks: Array<{
procId: string;
benchmarkType: string;
score: number;
deviation: number | null;
percentile: number;
sampleCount: number;
}> = [];
for (const file of BENCHMARK_FILES) {
const filePath = path.join(dataDir, file);
if (!fs.existsSync(filePath)) {
console.error(`File not found: ${filePath}`);
continue;
}
const content = fs.readFileSync(filePath, 'utf-8');
const rows = parseCSV(content);
const benchmarkType = file.replace('.csv', '');
for (const row of rows) {
// Store processor info
if (!processors.has(row.idproc)) {
processors.set(row.idproc, {
name: row.descproc,
vendor: extractVendor(row.descproc),
cores: extractCores(row.descproc),
});
}
// Parse performance
const { score, deviation } = parsePerf(row.perf);
if (score > 0) {
benchmarks.push({
procId: row.idproc,
benchmarkType,
score,
deviation,
percentile: parsePercentile(row.percentile),
sampleCount: parseInt(row.nbproc) || 1,
});
}
}
}
// Generate SQL
let sql = '-- Generated benchmark data\n\n';
// Insert processors
sql += '-- Insert processors\n';
const procArray = Array.from(processors.entries());
for (const [procId, info] of procArray) {
const cores = info.cores !== null ? info.cores : 'NULL';
sql += `INSERT OR IGNORE INTO processors (proc_id, name, vendor, cores) VALUES ('${escapeSQL(procId)}', '${escapeSQL(info.name)}', '${info.vendor}', ${cores});\n`;
}
sql += '\n-- Insert benchmark results\n';
for (const b of benchmarks) {
const deviation = b.deviation !== null ? b.deviation : 'NULL';
sql += `INSERT OR IGNORE INTO benchmark_results (processor_id, benchmark_type_id, score, score_deviation, percentile, sample_count)
SELECT p.id, bt.id, ${b.score}, ${deviation}, ${b.percentile}, ${b.sampleCount}
FROM processors p, benchmark_types bt
WHERE p.proc_id = '${escapeSQL(b.procId)}' AND bt.name = '${b.benchmarkType}';\n`;
}
// Output summary
console.log(`Processed ${processors.size} processors`);
console.log(`Processed ${benchmarks.length} benchmark results`);
// Write SQL file
fs.writeFileSync(path.join(__dirname, '../benchmark-seed.sql'), sql);
console.log('Generated benchmark-seed.sql');
}
main().catch(console.error);