A little script for profiling ;-)

More coming :wink:

I seriously miss the profiling feature in Unity, so I decided to create a little facility of my own. Obviously, there’s serious limitations to that, but at the same time, this approach also adds some freedom :wink:

Very simply put, the little “profiling framework” I’m offering here is used as follows:

  1. Add JCsProfiler to any of your game objects (ideally, make it so that it’s never destroyed!)

  2. In whichever method you need profiling, add the following code-pattern:

void Update() {
  JCsProfilerMethod pm = JCsProfiler.Instance.StartCallStopWatch(
    "ProfilingExample", gameObject.name, "Update");
  
  --- code to be profiled

  pm.CallIsFinished();
}

That’s it… there’s a few settings. I’m a bit in a rush now, want to continue with my game :wink: But I’ve attached a little sample project, which also includes a little Unity package that should contain all you need. You CAN use this with log4net, but I’ve commented that out so you don’t HAVE TO.

The profiling itself shouldn’t consume too much performance, rendering its GUI obviously does. That can be switched off, though (then, profiling only goes into the logfile). Also, if you make sure the statements are always in only one line (JCsProfilerMethod pm = … and pm.CallIsFinished()) you can very easily completely remove all profiling code. With VS.NET that’s two trival search / replace operations on all files in the project, takes about 10 seconds or so (for commenting everything in, or commenting everything out) :wink: … again, preprocessor directives would be COOL to make this even simpler and quicker (and easily available to everyone, not just those that use a code editor with full “project support”).

I haven’t even tried this with JavaScript but would be very happy to add a JavaScript sample, too, if someone takes the time to write it up (you just need to convert the sample I have created from C# to JavaScript… shouldn’t be too hard but I just don’t like JavaScript). It should be possible, actually, it should be easy :wink:

If people find this useful, I’ll put it to the UnifyWiki… See the screenshot for the little “addon” in action…

Jashan

PS: Oh, btw - the GUI code was the first UnityGUI 2.0 code I ever wrote. That sure could be optimized very easily (e.g. using CalcSize wisely instead of hardcoding heights that may or may not work with a given skin). Consider this “open source” and feel free to optimize, enhance and return the optimized version to the community, if you wish… I just did this because I couldn’t resist the pleasure of doing it :wink:

EDIT: In the original posting, I had uploaded a sample project which was missing the example scene. This should be fixed now :wink:

61445--2240--$jcsprofiler_182.png
61445–2241–$jcsprofilerdemoprojectv3_922.zip (568 KB)

Excellent! Thank you!

P.S. I played your awesome TRaceON game with another player from the IRC chat and I didn’t find out until afterwards that the server and other player was across the ocean!

Thank you, you’re welcome… You know, the funny thing is that I’m not even using the cool state synchronization features that Unity provides, and it still works smoothly most of the time. So far, I’ve not really done any “magic” to make the multiplayer mode work, it’s more or less “out of the box” - and if it turns out things don’t work well-enough, there’s plenty of room for optimization :slight_smile:

I have a rather “interesting” concept of how to support multiple game sessions in multiple levels on a single server though… we’ll see how that turns out, once I have implemented a few levels and all that stuff :wink:

Jashan

Hi Jashan ,
Thanks for writing this profiler, I really need to optimize my code but is there a way to use c# classes from “JavaScript” ? or do I need to rewrite the whole thing to JS in order to use it (which should be pretty straight forward as I understand…) ?

And another thing… any idea on how to optimize physics? I know in theory what I should do but a tool that will give me a report on what Physx is doing under the hood would be cool…

It should work when you put the classes into a folder named “Editor” in your Assets folder. That makes sure that my classes are compiled first so you should be able to use them from JavaScript.

Concerning PhysX: Sorry, not much of an idea … I’ve tried using the profiler that comes with the Apple development kit, and that might be the best available way to profile PhysX - but I’m not sure if you’ll be able to find the “hooks” you need to read the data spit out by that profiler in any meaningful way. What I think I was able to find out that way is that in my game, scripting only took about 3% of the time.

I think the tool was “Shark”.

Can I suggest posting this on the Wiki? It’s very cool and the Wiki seems like a much better place for storing code long term.
-Don

The editor folder thing didn’t work for me , still no access to c# classes and Unity didn’t allow me to attach scripts from the “Editor” folder on GameObjects. Tried it with the “Standard Assets” folder and still no luck.
What I did was to write a tiny adapter class that uses “GetComponent(String)” and dynamic typing to get access to the profiler class and instance and now all is good.
The only thing is that the adapter and the Profiler scripts should both be attached to the same GameObject.

I’m posting the JS project example .
Thanks again Jashan, you saved the day!
:smile:

91173–3566–$jcsprofiler_js_example_161.zip (528 KB)

Hi Don,

I’m planning to post both the profiler and the logger to the Wiki, but just didn’t have time for a final polish, yet. But maybe I should simply post it and polish it then (that’s one of the cool things on Wikis) :wink:

It’s nice to be able to add stuff like the solution to using this with JavaScript that UVRadiation had just posted (not having a proper solution for JavaScript was one of the things that kept me from posting it to the Wiki)…

Sunny regards,
Jashan

There is a small annoying issue with profiler in Unity 2, which is easy to fix. The profiler floods warnigs about MonoBehaviour and new.

JCsProfiler.cs:

public static JCsProfiler Instance {
    get {
        if (instance == null) {
            instance = new JCsProfiler();
        }
        return instance;
    }
}

Should be something as follows to prevent warnings:

public static JCsProfiler Instance {
     get {
         if (instance == null) {
            instance = FindObjectOfType(typeof (JCsProfiler)) as JCsProfiler;
         }
         return instance;
    }
}

Oh, thanks for the heads up! I had meanwhile changed that internally to the “Unity singleton pattern” but forgot to update the files here. This section now looks like this:

    /// <summary>
    ///     Returns the single instance of JCsProfiler (singleton-pattern).
    ///     Use this to access the profiler from anywhere in your code.
    /// </summary>
    public static JCsProfiler Instance {
        get { return instance; }
    }

    #region Initialization methods (Awake / Start)
    /// <summary>
    ///     Checks if this is a redundant instance of JCsProfiler and removes
    ///     itself, if this is the case. If not, sets the singleton instance
    ///     to this instance so other objects can access it.
    /// </summary>
    void Awake() {
        log.DebugFormat("{0}.Awake()", gameObject.name);
        if (instance != null) {
            Destroy(this);
        } else {
            instance = this;
        }
        log.DebugFormat("{0}.Awake() finished", gameObject.name);
    }

	/// <summary>Optionally starts putting profile results to logfile</summary>
	void Start() { 
        if (renderToLogging || renderToConsole) {
            StartCoroutine(AutomaticTextRendering());
        }
    }
    #endregion

I’m hoping to find some time soon to polish JCsLogger and JCsProfiler and then put it up to the Wiki in its (more or less :wink: ) final form.

Hi Jashan,

Just wanted to thank you for this code, very useful.

You’re welcome :slight_smile:

Maybe I’m missing something, but it doesn’t work for me on the device (iPhone). The GUI window is there, but no info inside. And if I check the output to console option, it doesn’t print out anything. In the Editor it works fine.

Could you please explain each parameter? What are the unit? I can’t find it in the code and there is no readme file. :frowning: