condensed version of console.trace() - javascript

JavaScript (browser): I want to find out how deep the stack is. Basically, I want to know how many lines would be printed if I would call console.trace(). But I don't want to call console.trace() (and then count lines in the console window), I just want to 'have' that number of lines in a variable which I can then store to get some kind of performance statistics. Here is an example.
function StackTest(limit){
this.inc = -1;
this.limit = limit;
}
StackTest.prototype.test = function(n){
//console.log(n);
if (n>this.limit){
console.trace();
return [n, this.inc];
}
this.inc += 2;
return this.test(n + this.inc);
}
test899 = new StackTest(899);
document.body.innerHTML = test899.test(0);
Above dummy code sums up odd numbers (which generates the sequence of square numbers), until the sum exceeds a given limit, here 899. So, we compute 1 + 3 + 5 + ... + 59 = 900; 900 is the first square exceeding our limit of 899.
The stack depth (for the innermost return) is 30 (as we summed up 30 numbers, namely the odd numbers below 60), and console.trace() will print out 30 lines (to be more exact, 30 lines referring to the last line of our test function)
I want this 30, but I don't want to call console.trace(). Neither do I want to modify my code and put in manual counters. Neither do I want anything specific to the dummy example (like depth = (1+this.inc)/2 or depth=Math.ceil(Math.sqrt(this.limit))); I want a generic way to get the 30 programmatically.
Is that possible?
I should mention: One thing which does not work: generating (not throwing, just creating) an Error with e = new Error('blah'), then doing e.stack, then doing .split('\n') on that to see how many lines there are. The reason this does not work is that the Error stack is 'cut down' to only the topmost couple of lines/frames of the 'real' stack. If there would be something like e.fullStack, that would give me what I want. If error objects as the above have the information I want, then I was unable to find it there.
UPDATE
one more thing which does not work: Error.captureStackTrace, taken from accepted answer to this question. It's 'cut down' also, and therefore, this really shouldn't be the accepted answer!!!
CLARIFICATION
What I'm doing is analyzing/comparing various performance measures of various algorithms. Among the performance measures are run time, space requirements, and stack depth (which is, kind of, a special case of 'space requirements'). The measures are graphed with the problem size on the horizontal axis, and run time etc vertically. To be able to construct graphs like this, obviously, it helps to have functions which do programmatically what otherwise would be done via debugger / console tools.
Please, please spare me with dull lectures about how I allegedly advocate some weirdo programming style, and other far-fetched assumptions on how I write code, just to construct an hallucinated argument for why I "don't need" and/or "shouldn't want" what I'm asking for. More angry rant (very optional)
If you have a rational argument against the existence of the feature, such as security concerns, different story, obviously.

Related

Frame rate independent exponential interpolation

I am creating a game.
I usually start with quick-and-dirty get-the-job-done code, and improve it later.
And precisely, I am trying to improve that.
Let's present the problem: the player controls an aircraft. When pressing a key, the aircraft rotates (a "pitch") and goes down (or up, depending on the key pressed).
When the player releases the key, the aircraft goes back to horizontal.
The maximum angle for the aircraft should be reached quickly, it's not a simulation. Think of Starfox.
The quick and dirty approach is as follows: each frame, I check if a relevant key is pressed.
The output of this step is a variable that contains either 0, -1 or +1 whether the aircraft should be horizontal, going down or going up.
Now, I do the following formula:
pitch = pitch*0.9 + maxAngle * turn * 0.1
turn is the variable obtained containing 0, -1 or +1.
This produces a nice effect. It's an interpolation, but not a linear one, which makes it more "fun" to watch.
Here is the problem: this formula doesn't contain the length of a frame. It's frame rate dependent.
I tried to extract the general formula. First, 0.9 and 0.1 are obviously what they are because they sum up to 1 (I didn't try to have one of them lesser than 0 and or one bigger than 2).
If I put that
a1=a0*x + b*(1-x)
I arrive at the general formula of
an = a0*(x^n) + b*(1-x)*(x^(n-1) + x^(n-2) + x^(n-3) + ... + 1 )
By assuming a certain frame length I could inject it into that, maybe, somehow, but I still don't know how to properly turn that into a function (especially this sum of x^n, I don't know how to factorize it).
The second problem is that, currently, the user can press and release the key as they like. By that, I mean by that the b in the equation can change (and the resolution I attempted does not take that into account).
So, this is the problem. In short, how to reverse engineer my own solution to inject the frame length in it so it becomes frame rate independent?
Please note that you can assume that the frame rate in the current program IS stable.
I am quite sure I am not the first one encountering such a problem. If you don't have a solution, hints are also welcome, of course.
Thanks

timing in Javascript acting strange

I am working on js to compare the performance of brute force O(n^2) and Barnes-Hut O(nlog(n))
In my code right now I am doing the same thing with the same data five times
like this:
let data = [arrays of 100 data];
let count = 5;
while(count>0){
count--;
console.time('brute force time' + iterationCount);
brute force function()
console.timeEnd('brute force time' + iterationCount);
console.time('BH time' + iterationCount );
Barnes Hut algorithm();
console.timeEnd('BH time' + iterationCount);
}
}
Though, the code is the same for each time, console.time is showing the different and worrying results.
In the timing, the difference between BH and brute force is not relatively similar in multiple iterations.
and it is not predictable when I run code every time.
One more thing to notice is that every time I run the code, in the first iteration brute force and Barnes Hut algorithm timing are almost similar where as after first, it shows that Barnes-Hut is way better.
PS: everything in both functions is scoped to each function i.e local variable and shares the same data in each iteration so in each iteration code is identical !!!!
can anyone help me understand why I am getting like this?
I'd guess these times are so tiny random noise affects the results - your machine doing other processing perhaps. I'd increase the data size, and therefore the processing time - maybe you'd see more consistent results then.

Accurately measure a Javascript Function performance while displaying the output to user

As you can see in code below, when I increase the size of the string it leads to a 0 milliseconds difference. And moreover there is an inconsistency as the string count goes on increasing.
Am I doing something wrong here?
let stringIn = document.getElementById('str');
let button = document.querySelector('button');
button.addEventListener('click', () => {
let t1 = performance.now();
functionToTest(stringIn.value);
let t2 = performance.now();
console.log(`time taken is ${t2 - t1}`);
});
function functionToTest(str) {
let total = 0;
for(i of str) {
total ++;
}
return total;
}
<input id="str">
<button type="button">Test string</button>
I tried using await too, but result is the same (see code snippet below). The function enclosing the code below is async:
let stringArr = this.inputString.split(' ');
let longest = '';
const t1 = performance.now();
let length = await new Promise(resolve => {
stringArr.map((item, i) => {
longest = longest.length < item.length ? longest : item;
i === stringArr.length - 1 ? resolve(longest) : '';
});
});
const diff = performance.now() - t1;
console.log(diff);
this.result = `The time taken in mili seconds is ${diff}`;
I've also tried this answer as, but it is also inconsistent.
As a workaround I tried using console.time feature, but It doesn't allow the time to be rendered and isn't accurate as well.
Update: I want to build an interface like jsPerf, which will be quite similar to it but for a different purpose. Mostly I would like to compare different functions which will depend on user inputs.
There are 3 things which may help you understand what happening:
Browsers are reducing performance.now() precision to prevent Meltdown and Spectre attacks, so Chrome gives max 0.1 ms precision, FF 1ms, etc. This makes impossible to measure small timeframes. If function is extremely quick - 0 ms is understandable result. (Thanks #kaiido) Source: paper, additional links here
Any code(including JS) in multithreaded environment will not execute with constant performance (at least due to OS threads switching). So getting consistent values for several single runs is unreachable goal. To get some precise number - function should be executed multiple times, and average value is taken. This will even work with low precision performance.now(). (Boring explanation: if function is much faster than 0.1 ms, and browser often gives 0ms result, but time from time some function run will win a lottery and browser will return 0.1ms... longer functions will win this lottery more often)
There is "optimizing compiler" in most JS engines. It optimizes often used functions. Optimization is expensive, so JS engines optimize only often used functions. This explains performance increase after several runs. At first function is executed in slowest way. After several executions, it is optimized, and performance increases. (should add warmup runs?)
I was able to get non-zero numbers in your code snipet - by copy-pasting 70kb file into input. After 3rd run function was optimized, but even after this - performance is not constant
time taken is 11.49999990593642
time taken is 5.100000067614019
time taken is 2.3999999975785613
time taken is 2.199999988079071
time taken is 2.199999988079071
time taken is 2.099999925121665
time taken is 2.3999999975785613
time taken is 1.7999999690800905
time taken is 1.3000000035390258
time taken is 2.099999925121665
time taken is 1.9000000320374966
time taken is 2.300000051036477
Explanation of 1st point
Lets say two events happened, and the goal is to find time between them.
1st event happened at time A and second event happened at time B. Browser is rounding precise values A and B and returns them.
Several cases to look at:
A B A-B floor(A) floor(B) Ar-Br
12.001 12.003 0.002 12 12 0
11.999 12.001 0.002 11 12 1
Browsers are smarter than we think, there are lot's of improvements and caching techniques take in place for memory allocation, repeatable code execution, on-demand CPU allocation and so on. For instance V8, the JavaScript engine that powers Chrome and Node.js caches code execution cycles and results. Furthermore, your results may get affected by the resources that your browser utilizes upon code execution, so your results even with multiple executions cycles may vary.
As you have mentioned that you are trying to create a jsPerf clone take a look at Benchmark.js, this library is used by the jsPerf development team.
Running performance analysis tests is really hard and I would suggest running them on a Node.js environment with predefined and preallocated resources in order to obtain your results.
You might what to take a look at https://github.com/anywhichway/benchtest which just reuses Mocha unit tests. Note, performance testing at the unit level should only be one part of your performance testing, you should also use simulators that emulate real world conditions and test your code at the application level to assess
network impacts, module interactions, etc.

Do I got number of operations per second in this way?

Look at this code:
function wait(time) {
let i = 0;
let a = Date.now();
let x = a + (time || 0);
let b;
while ((b = Date.now()) <= x) ++i;
return i;
}
If I run it in browser (particularly Google Chrome, but I don't think it matters) in the way like wait(1000), the machine will obviously freeze for a second and then return recalculated value of i.
Let it be 10 000 000 (I'm getting values close to this one). This value varies every time, so lets take an average number.
Did I just got current number of operations per second of the processor in my machine?
Not at all.
What you get is the number of loop cycles completed by the Javascript process in a certain time. Each loop cycle consists of:
Creating a new Date object
Comparing two Date objects
Incrementing a Number
Incrementing the Number variable i is probably the least expensive of these, so the function is not really reporting how much it takes to make the increment.
Aside from that, note that the machine is doing a lot more than running a Javascript process. You will see interference from all sorts of activity going on in the computer at the same time.
When running inside a Javascript process, you're simply too far away from the processor (in terms of software layers) to make that measurement. Beneath Javascript, there's the browser and the operating system, each of which can (and will) make decisions that affect this result.
No. You can get the number of language operations per second, though the actual number of machine operations per second on a whole processor is more complicated.
Firstly the processor is not wholly dedicated to the browser, so it is actually likely switching back and forth between prioritized processes. On top of that memory access is obscured and the processor uses extra operations to manage memory (page flushing, etc.) and this is not gonna be very transparent to you at a given time. On top of that physical properties means that the real clock rate of the processor is dynamic... You can see it's pretty complicated already ;)
To really calculate the number of machine operations per second you need to measure the clock rate of the processor and multiply it by the number of instructions per cycle the processor can perform. Again this varies, but really the manufacturer specs will likely be good enough of an estimate :P.
If you wanted to use a program to measure this, you'd need to somehow dedicate 100% of the processor to your program and have it run a predictable set of instructions with no other hangups (like memory management). Then you need to include the number of instructions it takes to load the program instructions into the code caches. This is not really feasible however.
As others have pointed out, this will not help you determine the number of operations the processor does per second due to the factors that prior answers have pointed out. I do however think that a similar experiment could be set up to estimate the number of operations to be executed by your JavaScript interpreter running on your browser. For example given a function: factorial(n) an operation that runs in O(n). You could execute an operation such as factorial(100) repeatedly over the course of a minute.
function test(){
let start = Date.now();
let end = start + 60 * 1000;
let numberOfExecutions = 0;
while(Date.now() < end){
factorial(100);
numberOfExecutions++;
}
return numberOfExecutions/(60 * 100);
}
The idea here is that factorial is by far the most time consuming function in the code. And since factorial runs in O(n) we know factorial(100) is approximately 100 operations. Note that this will not be exact and that larger numbers will make for better approximations. Also remember that this will estimate the number of operations executed by your interpreter and not your processor.
There is a lot of truth to all previous comments, but I want to invert the reasoning a little bit because I do believe it is easier to understand it like that.
I believe that the fairest way to calculate it is with the most basic loop, and not relying on any dates or functions, and instead calculate the values later.
You will see that the smaller the function, the bigger the initial overload is. That means it takes a small amount of time to start and finish each function, but at a certain point they all start reaching a number that can clearly be seen as close-enough to be considered how many operations per second can JavaScript run.
My example:
const oneMillion = 1_000_000;
const tenMillion = 10_000_000;
const oneHundredMillion = 100_000_000;
const oneBillion = 1_000_000_000;
const tenBillion = 10_000_000_000;
const oneHundredBillion = 100_000_000_000;
const oneTrillion = 1_000_000_000_000;
function runABunchOfTimes(times) {
console.time('timer')
for (let i = 0; i < times; ++i) {}
console.timeEnd('timer')
}
I've tried on a machine that has a lot of load already on it with many processes running, 2020 macbook, these were my results:
at the very end I am taking the time the console showed me it took to run, and I divided the number of runs by it. The oneTrillion and oneBillion runs are virtually the same, however when it goes to oneMillion and 1000 you can see that they are not as performant due to the initial load of creating the for loop in the first place.
We usually try to sway away from O(n^2) and slower functions exactly because we do not want to reach for that maximum. If you were to perform a find inside of a map for an array with all cities in the world (around 10_000 according to google, I haven't counted) we would already each 100_000_000 iterations, and they would certainly not be as simple as just iterating through nothing like in my example. Your code then would take minutes to run, but I am sure you are aware of this and that is why you posted the question in the first place.
Calculating how long it would take is tricky not only because of the above, but also because you cannot predict which device will run your function. Nowadays I can open in my TV, my watch, a raspberry py and none of them would be nearly as fast as the computer I am running from when creating these functions. Sure. But if I were to try to benchmark a device I would use something like the function above since it is the simplest loop operation I could think of.

CANNON.js: check if a body is being constrained

I've been trying to make a multiplayer game using javascript (most of which is on the server, using Node.js); one of the core mechanics I want to make is that players will be able to design their own fighting style (right down to how they swing their sword etc). Problem is that I can't find any simple way of constraining players' movements.
I first tried to write a method that checks then clamps the player's style so it doesn't look like they're breaking every limb simultaneously, but that didn't really work. I then found the wonderful CANNON.ConeTwistConstraint, but after looking through the documentation I've found that CANNON.js's constraints don't seem to have any sort of built-in function for just testing whether two bodies are exceeding the constraint's limits. I've thought about having my game just create objects in a separate simulation and check whether a force is being applied to either object, but I'm not sure about how to go about this, or if there's a better way.
Is there a simple/easier solution to my problem? If not, what would be the least CPU-intensive way of implementing the above?
You can manually check if the ConeTwistConstraint is hitting its limit. If you have a look at the method CANNON.ConeEquation.prototype.computeB, you can see that it computes the constraint violation, "g", using cos() and a dot product. You can simply do the same with the following code.
var eq = coneTwistConstraint.coneEquation;
var g = Math.cos(eq.angle) - eq.axisA.dot(eq.axisB);
if(g > 0) {
// Constraint limit exceeded
} else {
// Constraint is within limits
}
Using the same strategy, you can check if the twist limit is exceeded. Since the twist equation is a CANNON.RotationalEquation, the code becomes:
var eq2 = coneTwistConstraint.twistEquation;
var g2 = Math.cos(eq2.maxAngle) - eq2.axisA.dot(eq2.axisB);

Categories

Resources