четверг, 5 ноября 2009 г.

Кто быстрее ?

Здравствуйте, только-что копался в бэкапах и нашел небольшой скрипт, под названием Who Faster. Мне всегда было интиресно, что быстрее сработает if else if или switch, Array или Object, while или for, а также проверить на скорость небольшие скрипты, для этого в Firebug есть замечательные инструменты, но по каким-то причинам они меня не устраивали, по каким уже и не вспомню.
В общем тогда, я и решил написать этот скрипт, состоящий из парочки не хитрых функция, и показывающий, кто все-таки быстрее ! :)

В Поле пишите 
//CODE[название скрипта]:
....
//CODE:
...

Who Faster








Птицей "Use Loop" можно установить сколько раз прокручивать скрипт, чтобы победителя лучше видно было :).
Сам код(именно он и выполняется в программке выше):

function _Go(toTest,__length){
 var __end    = 0,
  __start  = 0;  
 var __toEval = '__start = +new Date;'+
  (__length>0?'for(var __i=0;__i<__length;__i++){'+
  toTest+'}':toTest)+
  '__end = +new Date - __start; ';
 try{ 
  eval(__toEval);
 }catch(err){
  __end = err;
 }
 return __end;
}  
function _test(){

 var txt_field= document.getElementById('_script_1');
 var max_loop=parseInt(document.getElementById('max_loop').value);
 var script   = txt_field.value;
 var res   = document.getElementById("_res");
 
 max_loop   = max_loop>0?max_loop:0;
  
 var arr_script = script.match(/\/\/CODE[^:]*:[^\/\/CODE]*/g);
 if(arr_script[0]=='')arr_script.shift();  
 var _res = "";
 var tmp  = [];
 for(var i=0,l=arr_script.length;i<l;i++){
  tmp = arr_script[i].match(/\/\/CODE([^:]*):([^¬]*)/); //
  _res += "<div><i>"+(tmp[1]==''?i:tmp[1])+
  ": </i><span>"+_Go(tmp[2], max_loop)+"</span></div>";   
  
 }  
 res.innerHTML = _res;
}

function de(name){
 var obj = document.getElementById(name); 
 if(obj.disabled){
  obj.disabled = false;
 }else{
  obj.disabled = 'disabled';
  obj.value  = '';
 }
}

вторник, 20 октября 2009 г.

Сортировка массивов методом Array.sort


Здравствуйте.
Перед нами задача отсортировать массив строк, в JavaScript существует метод для этого, и звать его Array.sort(),
Сортировка работает с помощью дополнительного, не обязательного параметра, без него метод будет сортировать по возрастанию значения элементов, например
['bb','a','c'].sort() -> ['a','bb','c'].
Посему написал несложную функцию для сортировки строк.

function StrSortByLength(arr,ASC_DESC){
 if(typeof(arr) ==  'string')arr = arr.split(' ');
 var cmp = function(a,b) {
  return a.length < b.length?-1:(a.length > b.length?1:0);   
 }
 return ASC_DESC=='DESC'?arr.sort(cmp).reverse():arr.sort(cmp); 
}
StrSortByLength(['bb','a','c']) // ['a','c','bb']
//или 
StrSortByLength('bb a c') // ['a','c','bb']

В первой строке ф-ции определяем тип передаваемого значения, если это строка то метод split(' ') разбивает ее на массив слов.

Суть функции cmp проста, принимает два аргумента(a,b) и возвращает:

a < b: Отрицательное значение.
a = b: Ноль 
a > b: Положительное значение.

Тесть функцию можно приспособить для своих нужд,
например мне нужно было отсортировать объекты по значению speed:

var _cmp = function (a,b) { 
 if (a.speed < b.speed)  return -1;
 if (a.speed > b.speed)  return 1;
 if (a.speed==b.speed) return 0; 
}; 

Второй параметр моей функции "ASC_DESC" при его отсутствии или значении не равному "DESC" сортировка происходит по возростанию -> ['a','c','bb']
если StrSortByLength('bb a c','DESC') // ["bb", "c", "a"]
Делается это очень просто, так-как массив уже отсортирован, необходимо лишь перевернуть элементы массива, методом reverse().
Надеюсь кому то пригодится. спасибо, Удачи :)

четверг, 8 октября 2009 г.

JavaScript возвращение :)

Здравствуйте, я долго и далеко пропадал, но любовь к JavaScript лишь крепчала :), поэтому решил продолжить писать заметки о JavaScript, и так...

Наверняка, кто-то уже такое написал и обсудил, в библиотеках это сделано точно, и все-же.
Допустим нам нужно создать DOM элемент с параметрами, например <div id='myDiv' style='border:1px solid black; color:red;'> и я очень часто вижу var obj = document.createElem... obj.style.border =... итд, если нужен один элемент то ещё ладно, но когда их несколько это очень много лишних строк кода. Решение очень простое.

function MakeElement(elName,attr){ 
 return SetAttr(document.createElement(elName),attr);
}
function SetAttr(el,attr){
 var a = '';
 for(a in attr){
     if(typeof attr[a] == 'object')SetAttr(el[a],attr[a]);
            else
            el[a] = attr[a];  
 }
  return el;
}
MakeElement('DIV',{'id':'myDiv','style':{'border':
'1px solid black','color':'red'}}); 
Можно оставить одну функцию SetAttr и выглядеть будет не менее симпатично.
function SetAttr(el,attr){
 var a = ''; 
 for(a in attr)
  if(typeof attr[a] == 'object')SetAttr(el[a],attr[a]);
        else el[a] = attr[a];  
}
SetAttr(document.createElement('DIV'),{'id':'myDiv','style':
{'border':'1px solid black','color':'red'}});
А вообще, очень часто банальную задачу, как взять элемент, присвоить стиль, в общем для действие решаемого в 5-10 строк кода подключают библиотеки и пишут 3-8 строк кода, это напоминает сайты на которых кнопки которые меняют фон при наведении сделаны на Flash :), да есть такое, пару дней назад видел.

вторник, 29 апреля 2008 г.

Зачем нам with ?

Иногда возникает соблазн поюзать with для изменения свойств обьекта. Удобно, красиво, но если протестировать, этот момент полуачается довольно ресурсоемким.
// Например, так лучше не делать !

with(obj.param){
height = 10;
width = 10;
}

// Проще и быстрее

var param = obj.param;
param.height = 10;
param.width = 10;

// Для IE разницы почти нету, а вот в FF прирост приличный !


вторник, 22 апреля 2008 г.

Оптимизируем getElementById

Данный метод пригодится для ajax приложений, где часто приходится обращаться к элементам по айди, оптимизировать можно кэшируя элементы, что приводит к серьезному приросту.


// Всё очень просто.
// В результате приблизительно +300% производительности.
var cache = [];
function $(id){
return !cache[id]?cache[id] =
document.getElementById(id):cache[id];
}

// немного модифицировал.
// ибо глобальные переменные часто приносят неприятности.
function $(id){
return !$.cache[id]?$.cache[id] =
document.getElementById(id):$.cache[id];
}
$.cache = [];

понедельник, 24 марта 2008 г.

Drag and Drop

Drag and Drop, при реализации D&D возникает кроссброузерная проблема с событиями, наша задача оптимизировать код, значит использовать как можно меньше условий.
В javascrpit к методам и свойствам обьекта можно обращаться как к ассоциативным массивам, тоесть запись window['alert']('Hello'); будет корректна, значит мы можем сделать предварительную проверку и установку нужных переменных в какойто обьект, затем использовать уже установленные корректные методы и свойства, избегая проверки на совместимость с браузерами.

Следуя всему этому написал такой код:

<script>

(function(){
// Браузер
var browser = {ie:false,opera:false,mozilla:false,safari:false};
browser[/ie/.test(navigator.userAgent.toLowerCase())?'ie':
/mozilla/.test(navigator.userAgent.toLowerCase())?'mozilla':
/opera/.test(navigator.userAgent.toLowerCase())?'opera':''
] = true;

// Назначение имён для свойств обьектов.
var ev = {}
ev.target = browser.ie?'srcElement':'target';
ev.pageY = browser.ie?'clientY':'pageY';
ev.pageX = browser.ie?'clientX':'pageX';
window.ev = ev;
})()
var obj = {};

function startDrag(e){
obj = document.getElementById('wnd');
obj.xoffset = e[ev.pageX] - parseInt(obj.style.left);
obj.yoffset = e[ev.pageY] - parseInt(obj.style.top);
document.onmousemove = draging;
document.onmouseup = endDrag;
}

function draging(e){
e = e||window.event
obj.style.top = e[ev.pageY] - obj.yoffset + "px";
obj.style.left = e[ev.pageX] - obj.xoffset + "px";
}

function endDrag(e){
document.onmousemove = null;
document.onmouseup = null;
}

</script>

четверг, 20 марта 2008 г.

Функция trim

Продолжая тему оптимизации работы со строками, можно вспомнить функцию trim и ее решение.

function trim (str){
return str.replace(/(^\s+)|(\s+$)/g, "");
}

Все чисто и понятно, но не так быстро как могло бы быть.
Результаты удаления пробелов из строки в 25000 символов.
IE6-IE7: 16ms;
FF: 16ms;
Opera: 15ms;
Как бы и немного, но можно гораздо быстрее

Как бы и немного, но можно гораздо быстрее.
function trim (str){
str = str.replace(/^\s\s*/, '');
var length = str.length;
while(/\s/.test(str.charAt(--length)));
return str.substring(0, length+1);
}

IE6-IE7: 0ms;
FF: 0ms;
Opera: 0ms;
Такой результат вполне понятен, скрипт не перебирает всю строку, а сперва добирается до порвого символа не пробел, затем с конца идёт цикл пока пробел.