Download utils/performance_optimizer.py from sourize/manimate: direct link, hf CLI and curl.
- Browser
- Download file 7.47 kB
-
https://huggingface.co/spaces/sourize/manimate/resolve/main/utils/performance_optimizer.py
- Command line
-
hf download hf://spaces/sourize/manimate/utils/performance_optimizer.py
-
curl -L -o performance_optimizer.py https://huggingface.co/spaces/sourize/manimate/resolve/main/utils/performance_optimizer.py
7.47 kB
| """ | |
| Performance optimization utilities for Manim rendering | |
| """ | |
| import re | |
| from typing import Dict, Tuple | |
| class PerformanceOptimizer: | |
| """Optimize rendering performance and resource usage""" | |
| # Quality settings for different performance levels | |
| QUALITY_SETTINGS = { | |
| "low_quality": { | |
| "flag": "-ql", | |
| "description": "Low Quality (Fast)", | |
| "resolution": "480p", | |
| "fps": 30, | |
| "max_duration": 10, | |
| "max_objects": 20, | |
| "performance_threshold": { | |
| "render_time": 60, # seconds | |
| "memory_usage": 1024 # MB | |
| } | |
| }, | |
| "medium_quality": { | |
| "flag": "-qm", | |
| "description": "Medium Quality (Balanced)", | |
| "resolution": "720p", | |
| "fps": 30, | |
| "max_duration": 15, | |
| "max_objects": 30, | |
| "performance_threshold": { | |
| "render_time": 180, # seconds | |
| "memory_usage": 2048 # MB | |
| } | |
| } | |
| } | |
| # Performance thresholds | |
| PERFORMANCE_THRESHOLDS = { | |
| "render_time": 300, # seconds | |
| "memory_usage": 4096, # MB | |
| "cpu_usage": 80 # percentage | |
| } | |
| def estimate_render_time(cls, quality: str, complexity: str = "medium") -> int: | |
| """Estimate rendering time in seconds""" | |
| base_times = { | |
| "low_quality": 30, | |
| "medium_quality": 60, | |
| "high_quality": 120, | |
| "production_quality": 300 | |
| } | |
| complexity_multipliers = { | |
| "simple": 0.5, | |
| "medium": 1.0, | |
| "complex": 2.0, | |
| "very_complex": 3.0 | |
| } | |
| base_time = base_times.get(quality, 60) | |
| multiplier = complexity_multipliers.get(complexity, 1.0) | |
| return int(base_time * multiplier) | |
| def analyze_code_complexity(cls, code: str) -> str: | |
| """Analyze code complexity to estimate render time""" | |
| complexity_indicators = { | |
| "simple": ["Text", "Write", "Create"], | |
| "medium": ["Transform", "FadeIn", "FadeOut", "MoveTo"], | |
| "complex": ["Axes", "plot", "FunctionGraph", "BarChart"], | |
| "very_complex": ["ThreeDScene", "rotate", "complex", "integral"] | |
| } | |
| code_lower = code.lower() | |
| scores = {"simple": 0, "medium": 0, "complex": 0, "very_complex": 0} | |
| for complexity, indicators in complexity_indicators.items(): | |
| for indicator in indicators: | |
| scores[complexity] += code_lower.count(indicator.lower()) | |
| # Determine overall complexity | |
| max_score = max(scores.values()) | |
| if max_score == 0: | |
| return "simple" | |
| return max(scores, key=scores.get) | |
| def get_recommended_quality(cls, prompt_length: int, has_complex_math: bool) -> str: | |
| """Recommend quality based on prompt complexity""" | |
| if prompt_length < 50 and not has_complex_math: | |
| return "medium_quality" | |
| elif prompt_length < 100: | |
| return "medium_quality" | |
| else: | |
| return "low_quality" # Start with lower quality for complex animations | |
| def optimize_code_for_performance(cls, code: str) -> str: | |
| """Optimize Manim code for better performance""" | |
| optimized_code = code | |
| # Limit excessive wait times | |
| optimized_code = re.sub(r'self\.wait\((\d+)\)', | |
| lambda m: f'self.wait({min(int(m.group(1)), 3)})', | |
| optimized_code) | |
| # Optimize animation run times | |
| optimized_code = re.sub(r'run_time=(\d+)', | |
| lambda m: f'run_time={min(int(m.group(1)), 5)}', | |
| optimized_code) | |
| # Add performance hints as comments | |
| performance_hints = [ | |
| "# Performance optimized: Limited wait times to 3 seconds max", | |
| "# Performance optimized: Limited animation run times to 5 seconds max" | |
| ] | |
| if any(hint.split(": ")[1] in optimized_code for hint in performance_hints): | |
| optimized_code = "\n".join(performance_hints) + "\n" + optimized_code | |
| return optimized_code | |
| def get_memory_efficient_settings(cls) -> Dict[str, str]: | |
| """Get settings for memory-efficient rendering""" | |
| return { | |
| "preview": True, | |
| "disable_caching": True, | |
| "low_quality": True, | |
| "save_last_frame": False, | |
| "write_to_movie": True | |
| } | |
| def calculate_estimated_file_size(cls, quality: str, duration: int = 10) -> Tuple[float, str]: | |
| """Calculate estimated output file size in MB""" | |
| # Rough estimates based on quality settings | |
| bitrate_estimates = { | |
| "low_quality": 1.0, # MB per minute | |
| "medium_quality": 3.0, | |
| "high_quality": 8.0, | |
| "production_quality": 25.0 | |
| } | |
| bitrate = bitrate_estimates.get(quality, 3.0) | |
| size_mb = (bitrate * duration) / 60 # Convert to actual duration | |
| if size_mb < 1: | |
| return size_mb * 1024, "KB" | |
| else: | |
| return size_mb, "MB" | |
| def get_optimization_tips(cls, quality: str, complexity: str) -> list: | |
| """Get optimization tips based on settings""" | |
| tips = [] | |
| if quality in ["high_quality", "production_quality"]: | |
| tips.append("Consider using medium quality for faster rendering during development") | |
| if complexity in ["complex", "very_complex"]: | |
| tips.append("Break complex animations into smaller scenes for easier debugging") | |
| tips.append("Use preview mode (-p flag) to quickly test animations") | |
| tips.append("Close other applications to free up system resources") | |
| tips.append("Ensure sufficient disk space for temporary files") | |
| return tips | |
| def optimize_quality(self, available_memory: float, estimated_render_time: float) -> str: | |
| if available_memory < self.PERFORMANCE_THRESHOLDS["memory_usage"]: | |
| return "low_quality" | |
| if estimated_render_time > self.PERFORMANCE_THRESHOLDS["render_time"]: | |
| return "low_quality" | |
| return "medium_quality" | |
| def estimate_render_time(quality_level: str) -> int: | |
| """Estimate render time based on quality level""" | |
| return PerformanceOptimizer.QUALITY_SETTINGS[quality_level]["performance_threshold"]["render_time"] | |
| def get_quality_settings(quality_level: str) -> dict: | |
| """Get quality settings for the specified level""" | |
| return PerformanceOptimizer.QUALITY_SETTINGS[quality_level] | |
| def optimize_for_performance(quality_level: str, scene_complexity: int) -> dict: | |
| """Optimize settings based on quality level and scene complexity""" | |
| settings = PerformanceOptimizer.QUALITY_SETTINGS[quality_level].copy() | |
| # Adjust settings based on scene complexity | |
| if scene_complexity > settings["max_objects"]: | |
| settings["max_objects"] = min(scene_complexity, settings["max_objects"] * 2) | |
| return settings |