In this specific case, I would talk about logic used for a single function while I was optimizing bytefx.
The problem
I've two numbers, x and y, I need to change x, adding or removing a "speed" value, while x is not equal to y.
This simple problem has a lot of solutions. This is probably the simplest one:
function xRun2y(x, y, speed) {
// check wich number is greater than other one
if(x < y) {
// ok, x is less than y ... then add speed
x += speed;
// x can't be greater than y ...
// x can be only less than y ... or equal
if(x > y)
x = y; // stop run
}
// other case, x is greater than y
else if(x > y) {
// well, in this case we remove speed from x
x -= speed;
// but x can't be lower than y ... then ...
if(x < y)
x = y;
}
// we don't need to care about x == y
// just return x
return x;
};
As you can see by yourself, this simple function could create a range of numbers from Nstart to Nend.
This is an example:
// from 10 to 0
var start = 10, end = 0, speed = 1,
arr = [];
while(start !== end) {
start = xRun2y(start, end, speed);
arr.push(start);
};
alert(arr); // 9,8,7,6,5,4,3,2,1,0
// from 0 to 10
var start = 0, end = 10, speed = 1,
arr = [];
while(start !== end) {
start = xRun2y(start, end, speed);
arr.push(start);
};
alert(arr); // 1,2,3,4,5,6,7,8,9,10
These operations should be usefull to move an element, to change some value from a startPoint to endPoint ... but, as i've said, there are different ways to do that.
This way is, for me, a better way to write the same function.
function xRun2y(x, y, speed) {
// check wich number is greater than other one
if(x < y)
// with a ternary operator we can do everything inline
x = x + speed > y ? y : x + speed;
// other case, x is greater than y
else if(x > y)
// well, in this case we remove speed from x
x = x - speed < y ? y : x - speed;
return x;
};
Simple ? Clear ? ... I like this way as I like ternary operator, it's a must to write compact but efficient code.
However, look at this last function ... don't You see something strange ?
If and else if do exactly same operations ... only plus sign and greater than are diferent.
How we could create these similar operations in a single line ?
Using eval, sure !
function xRun2y(x, y, speed) {
var temp = x < y ? ["+", ">"] : ["-", "<"];
return eval("x".concat(temp[0], "speed", temp[1], "y?y:x", temp[0], "speed")); };
Yess !!! ... seems perfect ? ... or seems the evil ? Let me explain that :)
function xRun2y(x, y, speed) {
// we need to create dedicated ternary operation
var temp = x < y ?
// if x is lower than y we need to add speed
// and verify that x + speed is not greater than y
["+", ">"] :
// in other case we need to remove speed from x
// and check if x is not lower than y
["-", "<"];
// if x is lower than y this string is:
// x + speed > y ? y : x + speed
// else if x is greater than y ...
// x - speed < y ? y : x - speed
return eval("x " + temp[0] + " speed " + temp[1] + " y ? y : x " + temp[0] + " speed"); };
... simple ? cool ? ... no, it's not cool !
Eval in this case isn't absolutely dangerous or a problem while ternary operator is.
The answer is simple, we have reduced code size with a simple and fast function but we do everytime two operations.
These are x + speed or x - speed in both cases duplicated.
It's true, a simple addiction shouldn't be a problem for code execution, but if there's a way to use a better function, why we shouldn't use that ?
function xRun2y(x, y, speed) {
if(x < y)
// we need minimum value because
// if x + speed is greater than y
// we want y
x = Math.min(x + speed, y);
else if(x > y)
// we need maximum value because
// if x - speed is lower than y
// we want y
x = Math.max(x - speed, y);
return x;
};
Final solution
We don't care about case x == y but an operation like this one Math.min(1,1) returns 1 and not an error than why we couldn't use ternary operator ?
function xRun2y(x, y, speed) {
return x < y ? Math.min(x + speed, y) : Math.max(x - speed, y);
};
Do you think this is the best way to run from a Number to another ? I think so :)
hi Andrea,
ReplyDeletei like the way you code,this function is absolutely useful!
p.s. I think this line
var temp = x <>"] : ["-", "<"];
should be
var temp = x < y ? ["+", ">"] : ["-", "<"];["+", ">"]
oops ... modified, thank you :)
ReplyDeleteyou just follow one of the first rules for javascript optimization:
ReplyDelete"Use built-in functions whenever possible (like the Math object), because these are generally faster than custom replacements. For critical inner loops, measure your changes because performance can vary among different browsers."
source of citation
come on kenta :)
ReplyDelete... I think this post is only for basic JS developers ...
... he he ... this post is "just for fun" but not every "young" js developer think over a single function more than 5 minutes ... then as you said, if you can, if you have more time, try to optimize your code, starting from these simple problems :)
Hey, Andrea.
ReplyDeleteI think you'll find it funny, 3 bytes less :D It's not any better - there are more operations to execute, but just a bit shorter:
function xRun2y2(x, y, speed) {
return Math[x < y ? "min" : "max"](x + --speed + (x < y), y);
};
Do you think it could be shortened more? :D
there are more operations to execute ... and there is an impossible sintax to debug ... no yaroslaff ... absolutely this is not what I mean when I talk about optimizzations ...
ReplyDelete...come on kenta :)...
ReplyDeleteyou misurestanding my previous comment, what I try to say is :
"Nice job, Nick! ;)"
Dude, Of course I didnt mean this as a serious variant. word "funny" means it :-)
ReplyDeleteI just felt like a challenge to find if there is could be a shorter syntax, no practical usage.
Sorry Yaroslaff, I've deleted your reply that was a cool solution:
ReplyDeletereturn Math[x < y ? "min" : "max"](x + --speed, y);
your reply that was a cool solution:
ReplyDeleteforget this reply because I didn't test wrong Yaroslaff "Inviz" Fedin solution ...
1 - it's wrong because doesn't work with float speed values
2 - it's wrong because my example creates an infinite loop with Inviz method ...
Then my last function is the final solution, bye.
Hello,
ReplyDeleteI'm probably less than a basic JS developers, but I have a lot appreciated this post!
Yet another buggy code :~)
ReplyDeleteThis is classical Arithmetic progression. But you. You changes :))))
What's happen if your magic var speed, defined with 0 :)))
You are guru :)))
http://style-bg.org/testuser/Translation.html
Thanks to read my blog until september 2006 to find something wrong, I hope you learned something in 3 years of posts.
ReplyDeleteRegards
Andrea, look. I don't like hate... You are good javascript programmer, but you have very very high spirits. This is not good for you, and your code. I thing, one man ever learn from another. And i hope, and i very kind if learn something else from you.
ReplyDeleteMy concept is: Ever ever before write something code, man who write this code, must be thinking.
Sometime when my english is better, i told you. I will happy if conversation with you.
With respect and please delete that from http://twitter.com. I don't need from unduly popularity ;)
Ever ever before write something code, man who write this code, must be thinking.
ReplyDeleteAgree, and that is the reason you started in a bad way, without thinking, and you'll go on forever, until the day you'll think before you'll write a comment which aim is to blame somebody else code.
Regards
Hm you are amazing.... Why, when i'm not thinking bugs in your code, not in my :~) Please stop this. Ugly dispute. I don't want talk with one fool man, who think is best ever JavaScript developer...
ReplyDeleteAfter previous post and this. We discovered, your code haves very big bugs. That bugs is harmful for user browser... That's enough.
You, don't guarantee anything? And i guarantee never use your code. Because i know, this code don't guarantee anything. Don't guarantee my job! Don't guarantee my calm sleep!
You can stop surf this blog right now, nobody stop you man.
ReplyDeleteKeep behaving like this and good like with your skills, right?
You are still commenting 3 years old post. Good luck with your life code a part, seriously! Go on, until I'll stop to publish your comments so you'll have something to truly blame about.
Regards
P.S. do you really think I gonn aremove that stuff from twitter? That's you man, right now, that's you! Good stuff!!!