Implement optional profiling for export
This commit is contained in:
parent
eb460a8e75
commit
0f3233d829
|
@ -30,6 +30,7 @@ import arm.material.cycles as cycles
|
|||
import arm.material.make as make_material
|
||||
import arm.material.mat_batch as mat_batch
|
||||
import arm.utils
|
||||
import arm.profiler
|
||||
|
||||
|
||||
@unique
|
||||
|
@ -127,7 +128,6 @@ class ArmoryExporter:
|
|||
self.world_array = []
|
||||
self.particle_system_array = {}
|
||||
|
||||
|
||||
# `True` if there is at least one spawned camera in the scene
|
||||
self.camera_spawned = False
|
||||
|
||||
|
@ -150,7 +150,8 @@ class ArmoryExporter:
|
|||
"""Exports the given scene to the given file path. This is the
|
||||
function that is called in make.py and the entry point of the
|
||||
exporter."""
|
||||
cls(context, filepath, scene, depsgraph).execute()
|
||||
with arm.profiler.Profile('profile_exporter.prof', arm.utils.get_pref_or_default('profile_exporter', False)):
|
||||
cls(context, filepath, scene, depsgraph).execute()
|
||||
|
||||
@classmethod
|
||||
def preprocess(cls):
|
||||
|
|
35
blender/arm/profiler.py
Normal file
35
blender/arm/profiler.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
import cProfile
|
||||
import os
|
||||
import pstats
|
||||
|
||||
import arm.log as log
|
||||
import arm.utils as utils
|
||||
|
||||
|
||||
class Profile:
|
||||
"""Context manager for profiling the enclosed code when the given condition is true.
|
||||
The output file is stored in the SDK directory and can be opened by tools such as SnakeViz.
|
||||
"""
|
||||
def __init__(self, filename_out: str, condition: bool):
|
||||
self.filename_out = filename_out
|
||||
self.condition = condition
|
||||
self.pr = cProfile.Profile()
|
||||
|
||||
def __enter__(self):
|
||||
if self.condition:
|
||||
self.pr.enable()
|
||||
log.debug("Profiling started")
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if self.condition:
|
||||
self.pr.disable()
|
||||
log.debug("Profiling finished")
|
||||
|
||||
profile_path = os.path.join(utils.get_sdk_path(), self.filename_out)
|
||||
with open(profile_path, 'w') as profile_file:
|
||||
stats = pstats.Stats(self.pr, stream=profile_file)
|
||||
stats.dump_stats(profile_path)
|
||||
|
||||
return False
|
|
@ -4,6 +4,7 @@ import os
|
|||
import platform
|
||||
import re
|
||||
import subprocess
|
||||
from typing import Any
|
||||
import webbrowser
|
||||
import shlex
|
||||
|
||||
|
@ -226,6 +227,11 @@ def get_relative_paths():
|
|||
addon_prefs = get_arm_preferences()
|
||||
return False if not hasattr(addon_prefs, 'relative_paths') else addon_prefs.relative_paths
|
||||
|
||||
def get_pref_or_default(prop_name: str, default: Any) -> Any:
|
||||
"""Return the preference setting for prop_name, or the value given as default if the property does not exist."""
|
||||
addon_prefs = get_arm_preferences()
|
||||
return default if not hasattr(addon_prefs, prop_name) else getattr(addon_prefs, prop_name)
|
||||
|
||||
def get_node_path():
|
||||
if get_os() == 'win':
|
||||
return get_sdk_path() + '/nodejs/node.exe'
|
||||
|
|
Loading…
Reference in a new issue