After reading this article: https://v8.dev/blog/elements-kinds. I was wondering if some of the arrays that are created in my code are packed or holey. Is there any way to check this at runtime in a browser environment(specifically Chrome)?
I am looking for something like a %DebugPrint() that works on Chrome.
Maybe there are some other clues that I can look for. For example, some info that is captured in heap snapshots, etc.
(V8 developer here.)
As far as I'm aware, Chrome (DevTools) does not expose arrays' "elements kind".
And that's probably okay, because the performance difference between "packed" and "holey" elements is very small. Essentially, it only shows up in microbenchmarks. The typical benefit of a packed array is that two machine instructions can be avoided that would otherwise have to happen. If you're looking at a one-line hot loop body that compiles to maybe a dozen machine instructions, then saving two of them can be measurable. If you're looking at a real-world app where hundreds of kilobytes of code contribute to overall performance, saving two machine instructions here and there isn't going to matter.
I understand that you may be curious; but as far as tangible optimizations go, there are much more impactful ways to spend your time. Talking about elements kinds is pretty much a "for your curiosity, here are some of the lengths to which JS engines go to squeeze every last bit of performance out of JavaScript" story; it is not meant to be important performance advice that most developers should be aware of.
Related
This is a bit of a strange question where I do not know enough to possibly ask it correctly, so I will do my best (googling for a worthwhile result has proven difficult):
You write a Javascript program
V8 (or other interpreters) compiles your script (I understand WHICH interpreter is running vastly changes the results of the answer to this, so let's stick with V8)
Your Javascript could be a formidably large footprint of executable code
Does V8 keep any routines that are not in use on the hard drive? Or does the Javascript interpreted commands stay completely in RAM?
I was wondering this because it would seem unfortunate for a massive JS program to eat into the available RAM allotment a browser gives if the complexity of the JS program was overtly large.
I know this gets into: if you have such a huge program you're doing it wrong, but I like to push things where I can and if I get a better understanding of how this all works, I can make better decisions :)
(V8 developer here.) Short answer: no, V8 does not swap any unused things (code or otherwise) to disk at runtime.
Executable code is typically not the biggest consumer of memory we see in V8, it tends to be dwarfed by (non-code) data. Still, the amount of code can certainly be significant; one of the reasons why V8 switched its first (unoptimized) execution tier from a compiler to an interpreter a few years ago was because that interpreter's bytecode is much smaller than the earlier non-optimizing compiler's machine code it replaced. When a function is optimized, it's still compiled to machine code; but since typically only relatively few functions get optimized, that usually only takes up a low single-digit percentage of overall memory.
In embedders that support it (like Chrome), V8 does support caching certain things between runs, including code. That's a performance optimization: some work can be avoided if you visit the same website multiple times. This mechanism doesn't temporarily free up any memory, and it's not supposed to.
Generally, it's not the job of individual applications to swap things to disk -- it's the job of the operating system. When all running applications combined use more memory than is available, then the kernel will pick some "pages" (chunks of memory) and write them to disk. Applications don't notice any of that (except a massive loss of performance when those pages are needed again) and don't have to do any work to support it. So this part of the answer applies not just to V8, but also to other JavaScript engines, and in general to all other programs you may run on your computer.
I have a heap profile taken in Chrome Dev Tools, but I am not sure how to interpret the data. As a test, I created 10,000 WidgetBuilder objects, each with their own methods. I would like to profile out storing methods on instances versus the prototype and see how that affects memory and performance when my page loads.
Should I focus on Retained Size or Shallow Size?
Are the values listed in these columns in bytes?
What is considered a lot of memory?
You might want to start here:
https://developers.google.com/chrome-developer-tools/docs/heap-profiling
It goes into detail on how to understand what you're reading. As for what is considered a lot of memory that's a tricky question. If your website is targeted at mobile devices I would start there as a constraint. To come up with a good comparison I'd suggest running the profiler against sites that you use every day and observe the memory consumption there.
If you find you're using more memory than gmail you might want to rethink ;)
I also recommend checking out jspref:
http://jsperf.com/prototype-vs-instance-functions
There is a LOT of prior work done on that site in regards to performance testing. You might be able to save yourself some time.
This might be a bit vague.
I'm working on an Atari 2600 emulator in javascript (http://jsatari.com/demo/ and https://github.com/docmarionum1/jsAtari) and it just runs incredibly slow. In chrome around 15-20 FPS and in Firefox around 2-3 FPS (on my computer).
I've run through my code optimizing with Chrome's and Firebug's profilers and optimized whatever I could, but I'm FAR from what I need and I don't see much more room for improvement in my algorithms. (Or, at least not without significantly diverging from the original hardware implementation.)
And so far my biggest improvements haven't come from improving the algorithms, but from changing my data structures:
Switching my large arrays (thousands of elements) to Typed Arrays provided the biggest boost in performance. Firefox would freeze before the switch, and Chrome ran about 10x faster.
I replaced some smaller arrays with individual variables and switch statements, also providing a significant boost in performance.
So, it seems pretty clear that arrays are incredibly slow.
In general, performance just seems very finicky, with small changes in my code resulting in large changes to the performance (for better or worse.) Or there other oddities that could be affecting the performance?
For instance, are objects created with object literal notation represented differently by the engine? I've seen noticeable changes in performance when merely adding or removing variables from an object, even if they weren't being used. Should the number of variables affect that?
Are there any other new developments in javascript (like Typed Arrays) that could have a big affect on performance?
And, finally, is there any good way to track performance due to intangibles like these? The profilers don't seem to help because the entire script with change, not just certain parts.
I saw, that you create many closures (and directly execute them) for example in your UpdatePos method. The massive creation usage of closures as you do it may be a big performance problem.
I would recomment you to take a look at JavaScript optimization tools like Closure Compiler by Google http://closure-compiler.appspot.com/home I really can recomment using this with Advanced Optimization (but then you have to give him all you javascript code - otherwise or if you use eval you (might) get problems (because he renames not only local variables and deletes unused code))
Here's four of them:
SunSpider JavaScript 0.9.1
V8 Benchmark Suite
Peacekeeper
Kraken 1.0
Different benchmarks tend to show a different browser as the king. Which one (including any one I may not have listed) is the most conclusive benchmark?
Sports analysts will never agree as to who is/was the best soccer player in history. Maradona? Pelé? Cruyff? Another one?
Different people regard some characteristics as more important than others, and give them more weight when forming an opinion. Same happens with benchmarks: no benchmark is absolutely right.
Find the benchmark that values the characteristics that you think are important for your particular program, and trust that one.
The one that does exactly what your application does.
Is there a tool/plugin/function for Firefox that'll dump out a memory usage of Javascript objects that you create in a page/script? I know about Firebug's profiler but I'd like something more than just times. Something akin to what Yourkit has for Java profiling of memory usage.
Reason is that a co-worker is using id's for "keys" in an array and is creating 1000's of empty slots when he does this. He's of the opinion that this is harmless whereas my opinion differs. I'd like to offer some proof to prove whether I'm right or not.
I haven't tried the Sofware verify tools, but Mozilla has tools that track overall memory consumed by firefox for the purpose of stemming leaks:
http://www.mozilla.org/performance/tools.html
and:
https://wiki.mozilla.org/Performance:Leak_Tools
There's also this guy saying to avoid large arrays in the context of closures, towards article bottom
http://ajax.sys-con.com/node/352585
I think JavaScript Memory Validator from Software Verification Limited can help you, it has allocations view, objects view, generations view, etc. It's not free but you can use the evaluation version to check your coworker's code. They also have a Performance and Coverage Validators...
See the source. Sparse arrays don't take up lots of memory, but if your colleague doesn't need any Array functionality, he should be using plain Objects anyway.
Try also about:memory which shows how much memory each window occupies and how much of it is dedicated to JS objects. It gives high level summary without per object usage, but it is a good starting point for investigating memory requirements of a site.
You can use Mozilla’s Developer Tools. In order to use advanced developer tools of Firefox you need to create a debug build instead of a release build. For more on building process, see the page. Also, more information about using Mozilla’s Developer Tools you can find in this paper.