heldentodd / xray-diffraction

This repository contains the code for one simulation, but eventually three are planned: bragg-law, Single Crystal Diffraction, and Powder Diffraction.
GNU General Public License v3.0
1 stars 1 forks source link

memory profiling #28

Open pixelzoom opened 4 years ago

pixelzoom commented 4 years ago

Related to #1 (code review), see the "Memory Leaks" section.

Here's the memory profiling for Chrome 83.0.4103.61 on macOS 10.15.4.

Time (minutes) Heap Size (MB)
0 12.5
2 22.2
4 38.5
6 92.1
8 57.8
10 28.4

This looks reasonable, memory grows but then shrinks. But I'm not familiar with whether this sim creates things statically or dynamically. And I don't see any calls to dispose, or implementation of dispose (see #25). So I'll turn this over to @heldentodd to confirm that there's no memory leak.

@heldentodd if you're not familiar with how to use Chrome to do heap-size comparisons, let me know and I'll provide details.

heldentodd commented 4 years ago

I think the memory is fine. I have run the sim for hours and when I stop it, the memory always comes down to less than 20 MB. When running full out with the craziest parameters, it can get up to 100-200 MB, but that goes away when the parameters are reset.

I'm much more worried about performance issues. I would like the sim to run about twice as fast, but I have not optimized for time because I don't know how to check it. Could you recommend a site that would tell me how to use (for example) the Chrome debugger to tell me how much processor time it takes to execute a segment of code? If it's too hard to explain, I think I can figure it out eventually, but I would really appreciate it if you can point me in the right direction.

pixelzoom commented 4 years ago

I'm not familiar with anything in Chrome dev tools that lets you profile a specific section of code. (That doesn't mean it's not there, just that I don't know about it :)

NaturalSelectionUtils.js has a couple of functions that might help you:

  /**
   * Determines the time that it takes to execute a specified function.
   * @param {function} someFunction - a function with no parameters and no return value
   * @returns {number} the time to complete someFunction, in ms
   * @public
   */
  time( someFunction ) {
    const tBefore = performance.now();
    someFunction();
    return performance.now() - tBefore;
  },

  /**
   * Logs the time that it takes to execute a specified function.
   * For example, if you want to time this:
   *   this.step( dt );
   * Wrap it like this:
   *   logTime( 'step', () => this.step( dt ) );
   * Console output will look like this:
   *   step took 56.68500000001586 ms
   *
   * @param {string} name
   * @param {function} someFunction - a function with no parameters and no return value
   * @public
   */
  logTime( name, someFunction ) {
    console.log( `${name} took ${NaturalSelectionUtils.time( someFunction )} ms` );
  },

Just wrap the section of code that you'd like to profile in a callback. For example, if you wanted to see how long the call to Lattice.updateSites takes in XrayDiffractionScreenView.js, then change this:

114      model.lattice.updateSites();

to this:

114    NaturalSelectionUtils.logTime( 'updateSites', () => model.lattice.updateSites() );

Not a good idea to have your sim depend on the natural-selection repository, so feel free to copy these functions to your own .js file. As noted by the "TODO" at the top of NaturalSelectionUtils.js, these functions may eventually move to PhET common code, but that's unlikely to happen for awhile.

pixelzoom commented 4 years ago

If you want to dive into the "Performance" tab of Chrome dev tools, the "Getting Started" documentation is at https://developers.google.com/web/tools/chrome-devtools/evaluate-performance. This is (for me) mostly useful when I need to locate a bottleneck. If you already know where the bottleneck is and want to incrementally refine the code to speed it up, then I prefer to instrument a specific section of code using the above logTime function.