Two loops performance difference. Swapping inner and outer loop - javascript

I had two loops (one nested in the other one) and I was wondering if there is any difference in how I nest these loops. Results of Code 1 and Code 2 are the same (100,000x4 = 4x100,000 = 400,000) but jsPerf shows that Code 2 is roughly 50% faster than Code 1.
I'd like to kindly ask for your advice, I don't understand the difference between the two.
Thank you very much.
var tt = function () {
// do some stuff
// for example:
return (3);
};
Test code 1:
for (var i = 0; i < 100000; i++) {
for (var j = 0; j < 4; j++) {
tt();
}
}
Test code 2:
for (var j = 0; j < 4; j++) {
for (var i = 0; i < 100000; i++) {
tt();
}
}

The difference is in the loop initialization code. The first code has to initialize the inner loop 100,000 times while the second one only does that 4 times.

Analyze the code as if each operation had a cost and you will see that this makes sense.
In test code 2, you are stuck on the nested loop 100,000 times, but go to the outer loop 4 times.
Instead, in test code 1, you alternate between the two.
The first test code runs more operations than the seconds.

Related

How to write a for loop in qml?

I am trying to add tick marks for dial on qml. I made the calculations and created the tick marks manually but want them to appear automatically based on the step size of the dial. My idea is to use a for loop but I don't know how to call the javascript in qml. Is the for loop the way to go and how does the code look like? Or do you have a better, more qml-like solution?
for i = (0,n):
gamma = alpha+i*delta
mix = sin (gamma) * (a+r+l/2)
miy = cos (gamma) * (a+r+l/2)
create tick mark i with mix, miy, gamma, l
end for
This is the logic that I want to put in the loop.
You should write your for loop inside a function like below:
function doing_in_loop() {
for (var i = 0; i < 9; i++) {
console.log(i)
}
}
or do in on a signal:
Component.onCompleted: {
for (var i = 0; i < 9; i++) {
console.log(i)
}
}
I think you can just do it like this:
for (var i = 0; i < 10; i++) {
}

Increment a variable by 3 in a loop that increments by 1

I want to create a loop where the "i" variable is incrementing by one (i++), and I want to add another variable "j" in the loop that increment not by one but 3 per 3 (so j+=3, and then the output looks like 0, 3, 6, 9, 12...).
I have tried so many thing, but here is my code that looks logic :
let j;
for (let i = 0; i < 24; i++) {
j = i += 3;
console.log(j); //It increments by 4, WTF ??
console.log(i); //Exactly the same whereas i should increments per 1
}
I also tried to create a variable "k" that is equal to "i" to leave "i" alone, but still doesn't work.
Thank you so much for your help guys :)
PS : Once solved, do you know how to make the variable j starts by 0 please ?
let j=0;
for (let i = 0; i < 24; i++) {
j+=3
console.log(j); //starts at 3, because in the first line of the function we say j = 0 + 3, so j=3, then once it loops again it gets +3 again, so it's 6 and so on.
console.log(i); //just increments by 1 each loop
Try this, is this what you were trying to achieve?
Like this - you can use comma separators in the initiator and loop statements in the for statement
for (let i = 0, j = 1; i < 24; i++, j += 3) {
console.log("i",i,"j",j);
}

Creating new array from unique elements found in array

I was given an assignment:
Finding unique elements in an array and creating a new array from these unique elements.
The professor gave us the pseudocode to code this assignment - it should be straightforward but my code is not working.
Here is my attempt:
// search for unique birthdays in the array
function find(birthdays) {
var uniqueBirthdays = [];
for (var i = 1; i <= birthdays.length; i = i + 2) {
var count = 0;
for (var j = 1; j <= birthdays.length; j = j + 2) {
if (birthdays[i] == birthdays[j]) {
count++;
}
}
if (count == 1) {
var n = uniqueBirthdays.length;
uniqueBirthdays[n] = birthdays[i - 1];
}
}
return uniqueBirthdays;
}
I have tried checking for indentation errors as well as a number of other things but can not figure out why as the array is traversed it is giving each element a count of only 1 (meaning there are no matching elements) - it does not seem to be traversing the array more than once so no elements have a count greater than 1 - even though I am using nested for loops.
I have increased the intervals by 2 because I need to compare every other element - there is a number assigned to each birthday so the array may look like:
['0001'][12/15]['0002'[03/12]...
I am brand new so I may be overlooking simple but ive tried so many things and i can not understand why this code isnt working - it is returning back all of the elements that are assigned to the birthdays instead of just the unique ones.
Any help that will point me in the right direction is very much appreciated.
You were very close, and there were just a couple mistakes. The only things that did not work were the way you wrote your for loops:
for (var i = 1; i <= birthdays.length; i = i + 2) {
Array indexes start at 0, so if you want to process the first element, use var i = 0;
Since these indexes start at 0, for an Array of 3 elements, the last index is 2. So you only want to run your loop while i is less than the array length: i < birthdays.length
You were skipping elements by doing i = i + 2. There seems to be no reason for it?
Something else worth mentionning: in JS, indentation does not matter - well, it does, but only to avoid making your eyes bleed. In fact, most websites use minified versions of their code, which fits on a single (often very long and ugly) line (example).
Here is your code, with only two lines fixed:
function find(birthdays) {
var uniqueBirthdays = [];
for (var i = 0; i < birthdays.length; i = i + 1) { // <-----
var count = 0;
for (var j = 0; j < birthdays.length; j = j + 1) { // <-----
if (birthdays[i] == birthdays[j]) {
count++;
}
}
if (count == 1) {
var n = uniqueBirthdays.length;
uniqueBirthdays[n] = birthdays[i];
}
}
return uniqueBirthdays;
}
// I used letters instead of birthdays for easier demo checking
var birthdays = ['a', 'b', 'a', 'c'];
console.log( find(birthdays) ); // ["b", "c"]
JS have direct methods tor that use Array.indexOf(), Array.lastIndexOf() and Array.filter()
uniques elements have same first position and last position
sample code:
const initailArray = [...'ldfkjlqklnmbnmykdshgmkudqjshmjfhmsdjhmjh']
const uniqueLetters = initailArray.filter((c,i,a)=>a.indexOf(c)===a.lastIndexOf(c)).sort()
console.log(JSON.stringify(uniqueLetters))

How to iterate over a JSON object in chunks of 3?

So i have a json object that is being served by nodejs.
I'm wanting to make articles in rows of 3, then div's in rows of 3 below the articles (that contain the information for the articles.
for (var infoset in jsonObj){
createArtRow(jsonObj[infoset][info]);
createDivRow(jsonObj[infoset][info]);
// creates an article, then a div one at a time
}
I'm having issues, because i'm unsure how to join the for loop iterating over the object (only 3 at a time).
for (var infoset in jsonObj){
for (var i = 0; i < 3; i ++) {
createArtRow(jsonObj[infoset][info]);
}
for (var i = 0; i < 3; i ++){
createDivRow(jsonObj[infoset][info]);
}
}
// ideally creates 3 articles, then 3 divs at a time.
I hope that makes sense.
Use a loop that increments by 3 instead of 1.
for (var i = 0; i < jsonObj.length; i += 3) {
// here you can use jsonObj[i], jsonObj[i+1], and jsonObj[i+2] to create a row
}
You could use modulus funcion, which i think is a cleaner more readable approach:
let i =0
for (var infoset in jsonObj){
If (i % 3 == 0 ){
createArtRow(jsonObj[infoset][info]);
}
createDivRow(jsonObj[infoset][info]);
i++;
}
Modulus (%) function works by deviding 'i' by the number after the % sign.
If the remainder is 0 (so exactly dividable by 3), it will be true and execute the code.

Breaking out of nested loops: return or label/break?

I am using a JavaScript function to set a global variable. Below, I have two really dumb example functions. One uses a label to break out of the nested loops. The other uses an empty return.
My question: which is better from a performance issue? (For the sake of argument, lets say you did this a few million times.)
Using empty return
function foo() {
for(var i = 0; i < 100; ++i) {
for(var j = 0; j < 100; ++j) {
if(i * j == 50) {
myGlobal = j;
return;
}
}
}
}
Using label and break
function foo() {
dance:
for(var i = 0; i < 100; ++i) {
for(var j = 0; j < 100; ++j) {
if(i * j == 50) {
myGlobal = j;
break dance;
}
}
}
}
I know that I will be doing nothing except finishing the function after my inner condition is met/I make my assignment.
Thanks!
After some testing (via Chrome console, MBP 2013, OSX 10.9, Intel i7 # 2.8GHz, 16GB DDR3), the results are very interesting. I ran two types of tests. The first tested using return and label/break to break out of a nested loop. The second used a straight return and label/break, with nothing else in the function. The test code:
function r() {
for(var i = 0; i < 10; ++i) {
for(var j = 0; j < 10; ++j) {
if(i*j == 50) {
return;
}
}
}
}
function b() {
dance:
for(var i = 0; i < 10; ++i) {
for(var j = 0; j < 10; ++j) {
if(i*j == 50) {
break dance;
}
}
}
}
function r2() {
return;
}
function b2() {
dance:
break dance;
}
var startTime;
var endTime;
console.log("Return test");
startTime = Date.now();
for(var i = 0; i < 1000000000; ++i) {
r2();
}
endTime = Date.now();
console.log(endTime - startTime);
console.log("Break test");
startTime = Date.now();
for(var i = 0; i < 1000000000; ++i) {
b2();
}
endTime = Date.now();
console.log(endTime - startTime);
When comparing breaking out of a the nested loops (functions r() and b() ), the return consistently performed significantly better. However, when using just the return or label/break in the function (functions r2() and b2() ) the label/break performed significantly faster. Test result breakdown:
Test 1, using 10000000 iterations
Average runtime (milliseconds) after 3 runs of using return to leave nested loops: 1215ms
Average runtime (milliseconds) after 3 runs of using label/break to leave nested loops: 1522ms
Test 2, using 1000000000 iterations //2 orders of magnitude more iterations
Average runtime (milliseconds) after 3 runs of using return: 1879ms
Average runtime (milliseconds) after 3 runs of using label/break: 1862ms
Thus:
For breaking nested loops, using return is ~25% faster
For science/HPC, using label/break is ~1% faster
I personally don't see anything wrong with empty return statements to abort execution early for a function that doesn't return anything normally. It's certainly cleaner than a label, and it's more language-agnostic too. A lot of languages don't support labeled for loops like whatever language your example is in, so the empty return statement will be simpler to understand for people coming from other languages lacking that feature.
Both have the same performance; the former arguably is more readable.
However, the latter makes it easier to modify the function should you need to add more instructions in the future after the loops.
UPDATE:
Good info here: Why JavaScript functions always return a value?, first answer says: 'Thus, return and function-executed-to-its-end semantics match.' So even if you use break, at the end of the execution it will return the same as if you use return

Categories

Resources