5 ms·
This isn't C, it's JavaScript. The semantics of a global variable read are a more complicated than you think. Global variables reside on the global object, whi
by tachyonbeam 12y ago
This isn't C, it's JavaScript.
The semantics of a global variable read are a more complicated than you think. Global variables reside on the global object, which can grow dynamically. Global properties can also be deleted at any time. Accessing a property which doesn't exist should throw an exception. Properties could also be getter functions, which would then result in a function call for every property read.
Have you written a JS compiler? Have you written a JIT compiler? Any kind of compiler for a real-world language? A garbage collector?
If someone knows of a way to get allocation statistics, then I can answer the question of how many allocations occur.
- acqq 12y ago> Global variables reside on the global object, which can grow dynamically. But it the example you give there's only one single variable. > Global properties can also be deleted at any time. Also doesn't happen in your example. > Accessing a property which doesn't exist should throw an exception. I agree. > Properties could also be getter functions, which would then result in a function call for every property read. But they aren't in your example. And all these aspects result in proportional increase in the resulting code, not in some unexpected complexity. > If someone knows of a way to get allocation statistics Run a Perl script (or Python script or do it by hand) that adds an increment of global nAllocations variable in front of any statement where you do a "new" of something. (If the most of the allocations are implicit, this counting maybe has to be added to the runtime of D, if it already doesn't exist. At least the runtime is open source, AFAIK). Run the program. Print that number. My guess is that it must be an order of 6 digits (millions) for the performance you measure. Which doesn't seem to be necessary to process 60000 evaluations of a single variable if more arrays of fixed sized things could be used in the process. I know for you it's "doctor, it hurts me when I press me here" "well don't do that" moment, but really, that's how it is. A lot of small objects allocated separately makes a lot of work for a GC and it's so in every language. The question is if the language provides you the possibility to do it more effectively. It does: structs and arrays. Yes, my bias is a bias of a C programmer, but there's a reason why good written C code is fast: the number of allocations is small, the most of stuff is preallocated before it's used. D lets you do the same. Note: changing the memory representation of the "objects" you use doesn't suggest you have to change your existing algorithms. It's just how the stuff is stored in memory. The changes to your code then aren't fundamentally significant, but you'll certainly get the initial speedup you need.
- mendort 12y agoI don't think anyone would argue that the compiler in question is far from optimal for compiling this particular program. However, if you are writing a general purpose compiler, you need to accommodate any program. Each of the properties (e.g. no use of getters, only one variable) that you point out about this program would take a compiler pass to establish. I haven't thought too much about it, but some of the properties are very likely to be undecidable by static analysis for many programs. It seems likely that using time to determine whether the program being compiled has these properties would not be efficient for most real world programs, even if it did provide enough information to choose a more optimal compilation strategy in some cases.
- tachyonbeam 12y agoIndeed, static analysis is generally rather costly. It's usually a fixed-point computation that iterates over the code multiple times. You generally need to allocate many objects to keep track of facts the analysis produces about different instructions, which need to be propagated around. Running a general-purpose static analysis on this test program would probably be more expensive than what I'm already doing. In the case of my minimalist test program, it's easy to say "well, ha! that's obviously not an accessor!", but in the general case, it's much harder. Consider, for example, that there could be load() or eval() statements in the code. That means invisible code you haven't seen yet, and can't analyze. Then consider a much more trivial case where you find this somewhere in the code: function foo(o) { delete o.a; } Now, you know that "o" is very unlikely to be the global object... But can you prove that with absolute certainty? It's possible you can't, so then you must assume that maybe the global variable "a" doesn't exist, and accesses to it might throw an exception. TL;DR: compiler design is no easy task.