Milliseconds of SetInterval() in chrome console - javascript

Can anyone please say what these numbers are. They are increasing so fast. Is that the no of times the function executes?
var time = setInterval(function() {
var b = document.getElementsByTagName('a')[22].innerHTML;
if (b == "name") {
document.getElementsByTagName('a')[22].click();
clearInterval(time);
} else {
console.log("sript started");
}
}, 10);

Those are the number of times the console.log("Script Activated") message has been triggered. Chrome automatically groups consecutively identical log messages rather than write it out each one on a new line. This makes it easier to see previous messages that would normally get scrolled off the top of the console too quickly.
In your case, the interval's callback function is triggering the log message every 10 milliseconds, so it's increment that count very quickly because it will occur 100 times a second.
EDIT: In a comment on another answer you asked why setting the interval value to 10000000000 caused the interval to go extremely quickly, rather than once every ~115 days.
This is because the number exceeds the maximum size a signed 32-bit integer can be is aproximately 2.1 billion (2,147,483,647). Once it exceeds that amount, it "wraps" around to the negative numbers. When setInterval() receives a negative number for the interval milliseconds, it simply rounds the value up to 4 milliseconds. This results in the interval occurring as quickly as possible, about 1000 times a second. I say "about" because there is no guarantee it will go this quickly on slower hardware.

It's console.log() output's times.
log one time show num 1, log two times show num 2.

Related

JavaScript: How to store, update, and calculate the average and total number of values in a set of user-generated times in seconds

This is a reaction tester project I've been working on
that shows you how fast you click a box or circle that appears randomly.
What I'm having trouble adding are two features: The ability to show the user how many attempts they've made,
and their average speed based on the sum of all times of their tries in seconds divided by their current total number of tries.
I've thought of a couple of different ways to get the number of tries: either counting the number of times the box appears, or since the best way
to record the seconds from each try seems to be to push those seconds into an array and sum them;
getting the length of that array would also give the number of tries.
The two places I'm stuck at are in trying to get the times to be stored into an array and summing them;
plus getting the number of tries and dividing that sum.
I've thought and worked on this at length, and any of my attempts that didn't yield the desired result will likely be confusing.
Here's the code that works:
createdTime=Date.now();
}, time);
}
document.getElementById("box").onclick=function()
{
clickedTime=Date.now();
reactionTime=(clickedTime-createdTime)/1000;
/*I'm trying to take make an array of reaction
times.
here is my last attempt:
recordTime = [];
sumTime = recordTime.push(reactionTime);
console.log(recordtime);
It only shows recordTime array once in the console as [undefined], and does not update the array with new reaction times. What I would expect/ am going for is something like:
first try/iteration>>box appears>>User Clicks>>reactionTime is measured and calculated>>recordTime: recordTime = [0.530];
second try/iteration>>box appears>>User Clicks>>reactionTime is measured and calculated>>recordTime: recordTime = [0.530, 0.511];
third try/iteration>>box appears>>User Clicks>>reactionTime is measured and calculated>>recordTime: recordTime = [0.530, 0.511, 0.353];
fourth try/iteration>>box appears>>User Clicks>>reactionTime is measured and calculated>>recordTime: recordTime = [0.530,
0.511, 0.353,...];
followed by:
sum(recordTime)/(recordTime.length);
(put recordTime result into innerHTML for desired element
id.)
(same for recordTime.length).
I've tried putting it both inside and outside
of the code above it, and none of my attempts have allowed me to add the seconds from reactionTime to an array.
Another option would be to add a "total seconds" span or element on the HTML page, and simply add the current time to the total time.
however, this still has me in much the same situation as to both how to make the javaScript "remember"
previous times, how to count the number of tries, and how to average them.
Thanks to A_A for the answer to my question. All I needed was a const Array=[0]; to store the values a user generated on a click. Thanks, A_A!
If you want to add an element to an array, you should not initialize it again (reactionTimes = []) as this will make it empty. Therefore initialize it in the beginning, and then call push on it.
const reactionTimes = [];
let startingTime;
function start() {
startingTime = Date.now();
}
function stop() {
const reactionTime = Date.now() - startingTime;
reactionTimes.push(reactionTime);
console.log(reactionTimes);
}
<button id="start" onclick=start()>Start</button>
<button id="stop" onclick=stop()>Stop</button>

Algorithm: randomly select points within user-defined intervals, separated by minimum user-defined values

I need to develop an algorithm that randomly selects values within user-specified intervals. Furthermore, these values need to be separated by a minimum user-defined distance. In my case the values and intervals are times, but this may not be important for the development of a general algorithm.
For example: A user may define three time intervals (0900-1200, 1200-1500; 1500-1800) upon which 3 values (1 per interval) are to be selected. The user may also say they want the values to be separated by at least 30 minutes. Thus, values cannot be 1159, 1201, 1530 because the first two elements are separated by only 2 minutes.
A few hundred (however many I am able to give) points will be awarded to the most efficient algorithm. The answer can be language agnostic, but answers either in pseudocode or JavaScript are preferred.
Note:
The number of intervals, and the length of each interval, are completely determined by the user.
The distance between two randomly selected points is also completely determined by the user (but must be less than the length of the next interval)
The user-defined intervals will not overlap
There may be gaps between the user-defined intervals (e.g., 0900-1200, 1500-1800, 2000-2300)
I already have the following two algorithms and am hoping to find something more computationally efficient:
Randomly select value in Interval #1. If this value is less than user-specified distance from the beginning of Interval #2, adjust the beginning of Interval #2 prior to randomly selecting a value from Interval #2. Repeat for all intervals.
Randomly select values from all intervals. Loop through array of selected values and determine if they are separated by user-defined minimum distance. If not (i.e., values are too close), randomly select new values. Repeat until valid array.
This works for me, and I'm currently not able to make it "more efficient":
function random(intervals, gap = 1){
if(!intervals.length) return [];
// ensure the ordering of the groups
intervals = intervals.sort((a,b) => a[0] - b[0])
// check for distance, init to a value that can't exist
let res = []
for(let i = 0; i < intervals.length; i++){
let [min, max] = intervals[i]
// check if can exist a possible number
if(i < intervals.length - 1 && min + gap > intervals[i+1][1]){
throw new Error("invalid ranges and gap")
}
// if we can't create a number in the current section, try to generate another number from the previous
if( i > 0 && res[i-1] + gap > max){
// reset the max value for the previous interval to force the number to be smaller
intervals[i-1][1] = res[i-1] - 1
res.pop()
i-=2
}
else {
// set as min the lower between the min of the interval and the previous number generated + gap
if( i > 0 ){
min = Math.max(res[i-1] + gap , min)
}
// usual formula to get a random number in a specific interval
res.push(Math.round(Math.random() * (max - min) + min))
}
}
return res
}
console.log(random([
[0900, 1200],
[1200, 1500],
[1500, 1800],
], 400))
this works like:
generate the first number ()
check if can generate second number (for the gap rule)
- if i can, generate it and go back to point 2 (but with the third number)
- if i can't, I se the max of the previous interval to the generated number, and make it generate it again (so that it generates a lower number)
I can't figure out what's the complexity, since there are random number involved, but might happen that with 100 intervals, at the generation of the 100th random number, you see that you can't, and so in the worst case this might go back generating everything from the first one.
However, every time it goes back, it shrinks the range of the intervals, so it will converge to a solution if exists
This seems to do the job. For explanations see comments in the code ...
Be aware, that this code does not do any checks of your conditions, ie non overlapping intervals and intervals are big enough to allow the mindist to be fulfilled. If the conditions are not met, it may generate erroneous results.
This algorithm allows the minimum distance between two values to be defined with each interval separately.
Also be aware, that an interval limit like 900 in this algorithm does not mean 9:00 o'clock, but just the numeric value of 900. If you want the intervals to represent times, you have to represent them as, for instance, minutes since midnight. Ie 9:00 will become 540, 12:00 will become 720 and 15:00 will become 900.
EDIT
With the current edit it also supports wrap-overs at midnight (Although it does not support intervals or minimum distances of more than a whole day)
//these are the values entered by the user
//as intervals are non overlapping I interpret
//an interval [100, 300, ...] as 100 <= x < 300
//ie the upper limit is not part of that interval
//the third value in each interval is the minimum
//distance from the last value, ie [500, 900, 200]
//means a value between 500 and 900 and it must be
//at least 200 away from the last value
//if the upper limit of an interval is less than the lower limit
//this means a wrap-around at midnight.
//the minimin distance in the first interval is obviously 0
let intervals = [
[100, 300, 0],
[500, 900, 200],
[900, 560, 500]
]
//the total upper limit of an interval (for instance number of minutes in a day)
//lenght of a day. if you don't need wrap-arounds set to
//Number.MAX_SAFE_INTEGER
let upperlimit = 1440;
//generates a random value x with min <= x < max
function rand(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
//holds all generated values
let vals = [];
let val = 0;
//Iterate over all intervals, to generate one value
//from each interval
for (let iv of intervals) {
//the next random must be greater than the beginning of the interval
//and if the last value is within range of mindist, also greater than
//lastval + mindist
let min = Math.max(val + iv[2], iv[0]);
//the next random must be less than the end of the interval
//if the end of the interval is less then current min
//there is a wrap-around at midnight, thus extend the max
let max = iv[1] < min ? iv[1] + upperlimit : iv[1];
//generate the next val. if it's greater than upperlimit
//it's on the next day, thus remove a whole day
val = rand(min, max);
if (val > upperlimit) val -= upperlimit;
vals.push(val);
}
console.log(vals)
As you may notice, this is more or less an implementation of your proposal #1 but I don't see any way of making this more "computationally efficient" than that. You can't get around selecting one value from each interval, and the most efficent way of always generating a valid number is to adjust the lower limit of the interval, if neccessary.
Of course, with this approach, the selection of next number is always limited by the selection of the previous. Especially if the minimum distance between two numbers is near the length of the interval, and the previous number selected was rather at the upper limit of its interval.
This can simply be done by separating the intervals by required many minutes. However there might be edge cases like a given interval being shorter than a seperation or even worse two consequent intervals being shorter than the separation in which case you can safely throw an error. i.e. had in [[900,1200],[1200,1500]] case 1500 - 900 < 30 been. So you best check this case per consequent tuples and throw an error if they don't satisfy before trying any further.
Then it gets a little hairy. I mean probabilistically. A naive approach would chose a random value among [900,1200] and depending on the result would add 30 to it and accordingly limit the bottom boundary of the second tuple. Say if the random number chosen among [900,1200] turns out to be 1190 then we will force the second random number to be chosen among [1220,1500]. This makes second random choice dependent on the outcome of the first choice and as far as I remember from probability lessons this is no good. I believe we have to find all possible borders and make a random choice among them and then make two safe random choices one from each range.
Another point to consider is, this might be a long list of tuples to start with. So we should care about not limiting the second tuple in each turn since it will be the first tuple on the next turn and we would like to have it as wide as possible. So perhaps getting the minimum possible value from the first range (limitting the first range as much as possible) may turn out to be more productive than random tries which might (most possibly) yield a problem in further steps.
I can give you the code but since you haven't showed any tries you have to settle with this rod to go and fish yourself.

Firebase functions - interval inside of an interval, to reduce invocations

The costs of using Firebase cloud functions becomes greater when the amount of invocations becomes greater.
I was wondering if that means that I can reduce the cost when I invoke/run a function x amount of times in a function. I've tested this and it turned out that the invocations were reduced.
This is what I mean:
exports.functionName = functions.region("europe-west2").pubsub.schedule('every 1 minutes')
.onRun((context) => { //counts as invocation
console.log("Running...")
var timesRun = 0;
var interval = setInterval(() => {
timesRun += 1;
if(timesRun === 6){
console.log("Stopping interval...")
clearInterval(interval);
}
console.log("Executing...")
//code... for example fetching json
}, 10000); //doesn't count as invocation
});
With this, I can run my code 5 times a minute, while the official invocation is equal to 1.
Is this really more efficient, or am I missing something?
With this, I can run my code 5 times a minute, while the official invocation is equal to 1. Is this really more efficient, or am I missing something?
With Cloud Functions you pay for both invocation count and CPU/memory usage duration. So while your approach reduces the number of invocations, it increases the amount of time you're using the CPU/memory.
Which one comes out cheaper should be a matter of putting the data into the pricing calculator.
Note that while the calculator shows only full seconds, you're actually billed for compute time per 100ms:
Compute time is measured in 100ms increments, rounded up to the nearest increment. For example, a function executing for 260ms would be billed as 300ms.
According to the documentation, your function times out after 1 minute, extended to 9 minutes.
Whatever you do into that time, will count as 1 execution time.
if you start interacting with other services like Firestore, those operations are billed separated.

HTML/Javascript Ascending Number

I'm trying to make a simple javascript game. Basically, you get pancakes at a certain amount per second. In the code, I call this value (the rate at which you get pancakes) pps. I want to make it so that as the HTML span tag that shows the total amount of pancakes gets more pancakes, (at the rate of pps), it ascends so it looks nicer.
For example, if I get pancakes at 5 pps, right now it just goes 0, 5, 10, etc... every second. I want it to go 0,1,2,3,4,5(1 second), next second 6,7,8,9,10, etc...
Here is the code that I have so far, for the pancake counter:
pps = 100;
tp = 0;
window.setInterval(function(){
tp += parseInt(pps);
document.getElementById("test").innerHTML = tp;
}, 1000);
Anyone know how to do this?
This is a problem common to all games, and one that you need to solve correctly for your game to work outside of your own computer.
The correct solution is that you need to measure the elasped time between each iteration of your game loop, or between each frame render. This is, in practice, going to be a very small number; you can think of this number as a "scaling factor".
If your game was about moving a space ship, and you wanted it to move 5 screen units per second, your game loop would:
Find the time elapsed since the last interval, in seconds. In a game rate-limited to 60 frames-per-second, this would be around 1/60th of a second
Multiply the ship's speed (5 units per second) by 1/60; the ship would move 0.8333... units this tick
move the ship by that amount.
By the time 1 full second has passed, the ship will have moved 5 units.
The exact same principal applies to your PPS.
The important part is that, in the real world, it will not be exactly 1/60th of a second between frames. If you're not computing the "scaling factor" each iteration of your loop, your game will slowly accrue error. setInterval is particularly bad for this, and not at all suitable as a source for time in a game.
The implementation in JavaScript is simple: Each game loop, record the current time from whatever source of time is available to you; in your case, you can use get Date().getTime(), which returns the time since the UNIX epoch in milliseconds. Record this value.
In the subsequent redraw, you will again call get Date().getTime(), and then subtract the previous value to the the elapsed time. That is your scaling factor, in milliseconds. You can multiply pps by that value to determine how many pancakes to add.
It's important that you still follow this approach, even if you're using setInterval. You might think you can simply setInterval(..., 1000 / 60) to invoke your callback 60 times per second, but setInterval (and setTimeout) are not accurate - they invoke your callback at least that far in the future, but potentially much further. You still need to scale pps by the elapsed times since the last redraw.
Here's a simple implementation:
var PPS = 5;
var lastTime = new Date().getTime();
var cakes = 0;
setInterval(function () {
var currentTime = new Date().getTime()
var elapsedTime = currentTime - lastTime;
lastTime = currentTime;
cakes += (PPS * (elapsedTime / 1000)) // elapsedTime is in milliseconds, divide by 1000 to get fractional seconds
document.getElementById('pps').innerText = cakes;
}, 10);
<div id="pps"></div>
As an aside, the incorrect solution is one you find in a lot of old games: Increment things as fast as you can. On old computers this was a viable solution; the game redrew slowly enough that the game would advance smoothly. As computers got faster, the game would run faster, until it became unplayable.
A simple interval timer would do the trick. Something like this:
function incrementToNumber(tag, currentNumber, targetNumber) {
var numTicks = targetNumber - currentNumber;
var interval = setInterval(function() {
currentNumber++;
tag.innerText = currentNumber;
if(currentNumber == targetNumber) {
clearInterval(interval);
}
}, 1000 / numTicks);
}
That particular function increments over the course of one second. To change the time it takes to increment, swap out the 1000 with whatever milliseconds you want it to take.
For a version that increases forever:
function inrementForever(tag, currentPancakes, pancakesPerSecond) {
setInterval(function() {
currentPancakes++;
tag.innerText = currentPancakes;
}, 1000 / pancakesPerSecond);
}

webkit profiler

what are the 'self' and 'total' columns? The 'total' column does not add up to 100% (much higher) and it looks like the self does. I suspect self is non-cumulative and total is. So if methodA calls methodB calls methodC, in self Id see the % for each method call individually, whereas in total methodA would show the total of all three methods, methodB would show the 2, and so on.
Is this correct?
Suppose you have this program:
main() calls A() calls B() calls C(), and C hangs in a loop for 10 seconds.
The CPU-profiler would say something like this:
total time: 10 sec
routine self% inclusive%
main 0 100
A 0 100
B 0 100
C 100 100
The self time of C would be 10 seconds, 100%. The self time of the others would be essentially zero.
The total (inclusive) time of every one of them would be 10 seconds or 100%. You don't add those up.
On the other hand, suppose C spends its 10 seconds doing I/O.
Then the CPU-only profiler would say something like this:
total time: 0 sec
routine self% inclusive%
main ? ?
A ? ?
B ? ?
C ? ?
because the only actual CPU time it uses is so short that basically no samples hit it, so to get the percents it is dividing by zero.
OTOH if the samples were on wall-clock time, you would get the first output.
A better type of profiler is one that samples the call stack, on wall clock time and tells you inclusive time as a percent of total, and gives it to you at the line-of-code level, not just for functions. That's useful because it's a direct measure of how much could be saved if the line were executed less, and almost no problem can hide from it. Examples of such profilers are Zoom and LTProf, and I'm told OProfile can do it. There's a simple method that works with any language and requires only a debugger.
Here's a discussion of the issues.

Categories