"""
Author: Leonardo de Sousa Marques
Affiliation: Embedded Computing Lab (ECL), Federal University of Santa Catarina (UFSC)
Description:
Utilitary functions to analyze execution time results.
"""
import json
from pathlib import Path
from typing import Dict, List
import numpy as np
[docs]
def load_json_file(json_file: Path) -> List[Dict]:
"""Loads and parses JSON file, returning list of experiments.
:param json_file: Path to the JSON file
:type json_file: Path
:return: List of experiment dictionaries
:rtype: List[Dict]
"""
try:
with open(json_file, 'r') as f:
data = json.load(f)
return data if isinstance(data, list) else [data]
except (json.JSONDecodeError, FileNotFoundError) as e:
print(f"Error loading {json_file.name}: {str(e)}")
return []
[docs]
def calculate_memory_overhead(baseline_value: float, current_values: List[float]) -> Dict[str, float]:
"""Calculates memory overhead percentage compared to baseline.
:param baseline_value: Baseline memory value in bytes
:type baseline_value: float
:param current_values: List of current memory values
:type current_values: List[float]
:return: Dictionary with overhead_percent, baseline_bytes, current_bytes, or empty dict
:rtype: Dict[str, float]
"""
if not current_values or baseline_value == 0:
return {}
median = np.median(current_values)
overhead = ((median - baseline_value) / baseline_value) * 100
return {
'overhead_percent': overhead,
'baseline_bytes': baseline_value,
'current_bytes': median
}
[docs]
def get_metric_title(metric: str) -> str:
"""Gets appropriate title for a metric.
:param metric: Metric key
:type metric: str
:return: Human-readable title for the metric
:rtype: str
"""
return {
"time_ns": "Execution time",
"max_memory_usage": "Max memory usage",
"memory_overhead": "Memory overhead"
}.get(metric, metric)
[docs]
def get_metric_ylabel(metric: str) -> str:
"""Gets appropriate y-axis label for a metric.
:param metric: Metric key
:type metric: str
:return: Y-axis label string
:rtype: str
"""
return {
"time_ns": "Time (s)",
"max_memory_usage": "Memory Usage (MB)",
"memory_overhead": "Memory Overhead (%)"
}.get(metric, metric)
[docs]
def save_plot(output_dir: Path, codec_name: str, format: str, metric: str) -> None:
"""Saves the current plot to file.
:param output_dir: Directory to save the plot
:type output_dir: Path
:param codec_name: Name of the codec
:type codec_name: str
:param format: File format (e.g., pdf, png)
:type format: str
:param metric: Metric name for filename
:type metric: str
:return: None
:rtype: None
"""
import matplotlib.pyplot as plt
output_dir.mkdir(parents=True, exist_ok=True)
filename = f"{codec_name}_{metric}_metrics.{format}"
plt.savefig(output_dir / filename, bbox_inches='tight')
[docs]
def save_json_file(filepath: Path, data: Dict, description: str = "") -> None:
"""Saves data to a JSON file.
:param filepath: Path to the output file
:type filepath: Path
:param data: Data to serialize to JSON
:type data: Dict
:param description: Optional description to print, defaults to ""
:type description: str, optional
:return: None
:rtype: None
"""
filepath.parent.mkdir(parents=True, exist_ok=True)
with open(filepath, 'w') as f:
json.dump(data, f, indent=2)
if description:
print(f" {description}: {filepath}")