Untitled

 avatar
unknown
plain_text
14 days ago
3.2 kB
3
Indexable
interface PerfResult {
  timestamp: string;
  provider: string;
  userOperationHash: string;
  duration_ms: number;
  success: boolean;
}

interface ProviderStats {
  count: number;
  totalDuration: number;
  minDuration: number;
  maxDuration: number;
  successCount: number;
}

function analyzePerformance(data: PerfResult[]) {
  // Group results by provider
  const resultsByProvider = data.reduce((acc, result) => {
    if (!acc[result.provider]) {
      acc[result.provider] = [];
    }
    acc[result.provider].push(result);
    return acc;
  }, {} as Record<string, PerfResult[]>);

  // Find minimum sample count across providers
  const minSamples = Math.min(
    ...Object.values(resultsByProvider).map((results) => results.length)
  );

  // Take equal samples from each provider
  const equalizedData: PerfResult[] = [];
  Object.entries(resultsByProvider).forEach(([provider, results]) => {
    equalizedData.push(...results.slice(0, minSamples));
  });

  // Group by provider
  const stats = new Map<string, ProviderStats>();

  // Initialize stats for each provider
  equalizedData.forEach((result) => {
    if (!stats.has(result.provider)) {
      stats.set(result.provider, {
        count: 0,
        totalDuration: 0,
        minDuration: Infinity,
        maxDuration: -Infinity,
        successCount: 0,
      });
    }

    const providerStats = stats.get(result.provider)!;
    providerStats.count++;
    providerStats.totalDuration += result.duration_ms;
    providerStats.minDuration = Math.min(
      providerStats.minDuration,
      result.duration_ms
    );
    providerStats.maxDuration = Math.max(
      providerStats.maxDuration,
      result.duration_ms
    );
    if (result.success) providerStats.successCount++;
  });

  // Convert to table format
  const tableData = Array.from(stats.entries()).map(([provider, stats]) => ({
    Provider: provider,
    "Sample Count": stats.count,
    "Avg Duration (ms)": (stats.totalDuration / stats.count).toFixed(2),
    "Min Duration (ms)": stats.minDuration.toFixed(2),
    "Max Duration (ms)": stats.maxDuration.toFixed(2),
    "Success Rate": `${((stats.successCount / stats.count) * 100).toFixed(1)}%`,
    "P95 Duration (ms)": calculateP95(
      equalizedData
        .filter((r) => r.provider === provider)
        .map((r) => r.duration_ms)
    ).toFixed(2),
  }));

  // Print results
  console.log(
    `\n=== Provider Performance Analysis (${minSamples} samples each) ===\n`
  );
  console.table(tableData);

  // Find best performing provider
  const bestProvider = tableData.reduce((best, current) => {
    const currentAvg = parseFloat(current["Avg Duration (ms)"]);
    const bestAvg = parseFloat(best["Avg Duration (ms)"]);
    return currentAvg < bestAvg ? current : best;
  });

  console.log("\n=== Best Performing Provider ===");
  console.log(
    `${bestProvider.Provider} with average latency of ${bestProvider["Avg Duration (ms)"]}ms`
  );
}

function calculateP95(durations: number[]): number {
  const sorted = durations.sort((a, b) => a - b);
  const index = Math.ceil(sorted.length * 0.95) - 1;
  return sorted[index];
}

// Your JSON data
const perfResults = [] as PerfResult[];

analyzePerformance(perfResults);
Leave a Comment