Skip to content

Commit

Permalink
Merge pull request #1977 from MoritzBrueckner/profiler
Browse files Browse the repository at this point in the history
Implement optional profiling for export
  • Loading branch information
luboslenco committed Oct 31, 2020
2 parents 4236190 + 25ed205 commit 91c98c7
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
5 changes: 3 additions & 2 deletions blender/arm/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import arm.material.make as make_material
import arm.material.mat_batch as mat_batch
import arm.utils
import arm.profiler


@unique
Expand Down Expand Up @@ -127,7 +128,6 @@ def __init__(self, context: bpy.types.Context, filepath: str, scene: bpy.types.S
self.world_array = []
self.particle_system_array = {}


# `True` if there is at least one spawned camera in the scene
self.camera_spawned = False

Expand All @@ -150,7 +150,8 @@ def export_scene(cls, context: bpy.types.Context, filepath: str, scene: bpy.type
"""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):
Expand Down
35 changes: 35 additions & 0 deletions blender/arm/profiler.py
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions blender/arm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import platform
import re
import subprocess
from typing import Any
import webbrowser
import shlex

Expand Down Expand Up @@ -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 getattr(addon_prefs, prop_name, default)

def get_node_path():
if get_os() == 'win':
return get_sdk_path() + '/nodejs/node.exe'
Expand Down

0 comments on commit 91c98c7

Please sign in to comment.