Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Переменная в классе или датасете (https://javascript.ru/forum/misc/73828-peremennaya-v-klasse-ili-datasete.html)

somejs 18.05.2018 21:19

Переменная в классе или датасете
 
Приветствую всех. Как-то так вышло, что еще давно пришла в голову идея передавать переменные из html в js через имя или класс. Уже как давно используется dataset. Но, вот, провел эксперимент:
Создал обычный селект (эта часть кода не входит в эксперимент):
var select = document.createElement("select");
select.classList.add("a-b-c");
select.id = "s";
select.dataset.info = "{'a':'a','b':'b','c':'c'}";
document.body.appendChild(select);

А вот тут уже пошел эксперимент - извлекаю переменные при помощи резки:

var result = document.getElementById('s').className.toString(). split("-");
console.log(result);

и при помощи датасета:

var resultx = document.getElementById('s').dataset.info;
console.log(resultx);

Результат получился такой:
(3) ["a", "b", "c"]
name time = 3.6999999974796083

{'a':'a','b':'b','c':'c'}
dataset time = 15.700000003562309

Во сколько раз быстрее даже со split получается извлечь переменные из класса. Но загрузил код в бенчмарк (http://jsben.ch) и получил такую, вот, картинку (в приложении). Дык, как это работает, что быстрее, стоит ли извращаться или спокойно использовать датасеты? Интересны адекватные объяснения.
https://scontent.fiev2-1.fna.fbcdn.n...&oe=5 B9A109A

j0hnik 18.05.2018 21:30

document.getElementById('s').className.toString(). split("-");

класснейм уже стринг

somejs 18.05.2018 22:26

Лишнее настрочил, согласен. Но на скорость не повлияло все равно.
http://jsben.ch/C7q0c

somejs 18.05.2018 22:30

Проделал несколько раз и получается такая картина, что датасет первый раз исполняется медленнее, но затем набирает скорости и исполняется быстрее. А бывает так, что датасет сразу выдает хорошие результаты. Однако у меня на локалхосте датасет все равно проигрывает.

j0hnik 18.05.2018 22:49

somejs,
Раз ваш датасет быстрей и без доп заморочек используйте его.

j0hnik 18.05.2018 22:58

когда гоняют бенчмарки для того чтобы увидеть конкретную разницу методов, все общие методы и вообще весть код который к ним не относится из теста выносят нафик, оставляя только то, без чего тестировать не удастся.

j0hnik 18.05.2018 22:59

http://jsben.ch/bxpw5

somejs 18.05.2018 23:17

j0hnik,
Благодарю за правку теста. Вынес также у себя на локалхосте. Результат такой:
name time = 0.09999999747378752

dataset time = 15.900000005785841

Что-то не шуточно проигрывает датасет, когда бенчмарк говорит об обратном.

Вот, сохраните в хтмл и запустите. В идеале, методы делал на две страницы, а тут слил для удобства сбросить.

<html>

<body>
<p id="p1"></p>
<p id="p2"></p>
<script type="text/javascript">
var select = document.createElement("select"); 
select.classList.add("a-b-c"); 
select.id = "s"; 
select.dataset.info = "{'a':'a','b':'b','c':'c'}"; 
document.body.appendChild(select); 
var el = document.getElementById('s');

var time = performance.now();

// some code 
el.className.split("-");

time = performance.now() - time;
document.getElementById('p1').innerHTML="name time = "+time;


var timex = performance.now();

// some code 
el.dataset.info;

timex = performance.now() - time;
document.getElementById('p2').innerHTML="dataset time = "+timex;
</script>
</body>
</html>

рони 18.05.2018 23:28

Цитата:

Сообщение от somejs
Вот, сохраните в хтмл и запустите.

[HTML run][/HTML]

:-?

j0hnik 18.05.2018 23:35

somejs,
[HTML run][/HTML]
-запускаемый код

переставьте ваши замеры местами и увидите другой результат.

а еще тест от теста разброс огромный

чтобы performance хоть как то адекватно показал скорость нужен цикл и много итераций, их количество зависит от "тяжести" кода.

для того и существуют бенчмарки, чтобы не заворачиваться а закинуть и посмотреть.

https://jsperf.com/ - этот я считаю самым адекватным, в вашем присутствует разброс. больше 1%, (раз замерил 83%, повторно мерию +84%)

j0hnik 18.05.2018 23:39

somejs,
у меня вообще ваш тест по нулям периодически показывает. :D

name time = 0

dataset time = 0

время настолько мало

рони 18.05.2018 23:40

:write:
select.info fastest :)

j0hnik 18.05.2018 23:42

Цитата:

Сообщение от рони
select.info fastest

неуловил

рони 18.05.2018 23:53

j0hnik,
протестируй

select.info =  ["a", "b", "c"] ;


вместо select.dataset.info = "{'a':'a','b':'b','c':'c'}";

j0hnik 19.05.2018 00:42

рони,
Быстрей. если ему видимость в атрибутах не нужна, вполне можно использовать.

somejs 19.05.2018 02:00

Спасибо за тэги - с ними я еще не разобрался.
Да, по 20-40 итераций делал и повторюсь, в отдельных файлах было, даже если менять местами в одном, то считывать с класса и резать быстрее. Тестирую на слабом (по нынешним меркам) железе. Где-то на 5-7 раз датасет работает как класс, а то и чуть быстрее, но даже при 40 итерациях среднее не дотягивает до класса. Все же датасет работает медленнее. Вот, статья, в которой это тоже упоминается:
https://intuio.at/blog/dont-use-data...ments-with-js/

Меня удивили показания бенчмарка, ибо на реальной машине датасет не лидирует. Почему так происходит - не понятно. В целом, вы правы, на современных компьютерах это все милисекунды, которые не заметны, но ради оптимизации хотелось все же разобраться в этом.

somejs 19.05.2018 02:11

Цитата:

Сообщение от рони (Сообщение 485612)
j0hnik,
select.info =  ["a", "b", "c"] ;

вместо select.dataset.info = "{'a':'a','b':'b','c':'c'}";

Мне было удобней использовать объект, но для чистоты эксперимента исправил на массив. Время не улучшилось в сторону датасета:

name time = 0
dataset time = 15.199999994365498

С итерацией в 50:
name time = 0.20000000222353265
dataset time = 60.199999999895226

j0hnik 19.05.2018 02:15

<html>

<html>

<body>
<p id="p1"></p>
<p id="p2"></p>
<p id="p3"></p>
<script type="text/javascript">
var select = document.createElement("select"); 
select.classList.add("a-b-c"); 
select.id = "s"; 
select.dataset.info = ["a", "b", "c"]; 
select.info = ["a", "b", "c"]; 
document.body.appendChild(select); 
var el = document.getElementById('s');

var p2 = performance.now();
for (var i = 0; i < 100000; i++) el.dataset.info;
s2 = performance.now() - p2;

var p1 = performance.now();
for (var i = 0; i < 100000; i++) el.className.split("-");
s1 = performance.now() - p1;


var p3 = performance.now();
for (var i = 0; i < 100000; i++) el.info;
s3 = performance.now() - p3;



document.getElementById('p2').innerHTML="dataset time = "+s2;
document.getElementById('p1').innerHTML="name time = "+s1;
document.getElementById('p3').innerHTML="info = "+s3;
</script>
</body>
</html>

//========================
хром
name time = 20.700000000942964
dataset time = 10.800000003655441
info = 1.5999999959603883
//========================
FF
name time = 4.284999999999997
dataset time = 12.164999999999992
info = 1.2399999999999807

j0hnik 19.05.2018 02:17

somejs, походу вы в FF тестируете, а я в хром вот результаты и отличаются

somejs 19.05.2018 02:32

Ой, извиняюсь. Да, - timex (правка при слиянии, добавил х, чтобы не было вмешательств).
Так получается при 70:
name time = 0.09999999747378752
dataset time = 0.09999999747378752

В принципе, разницы нет.

Спасибо за ссылку на бенчмарк, кстати.

j0hnik 19.05.2018 02:37

somejs,
мой тест запустите, что у вас покажет, в FF быстрей класснейм даже несмотря на сплит! В хром датасет.

somejs 19.05.2018 02:40

Результат вашего кода:
name time = 33.90000000217697
dataset time = 23.400000005494803
info = 2.899999999499414
(Spartan, Chrome, Firefox - везде одинакого, почему-то)

Интересно. Имеет ли место 100 тыс итераций при наличии 10-12 селектов?
Но теперь понятно, откуда такой результат у бенчмарков. Спасибо!

j0hnik 19.05.2018 02:45

somejs,
100т это условно, так чтобы уменьшить погрешность.

somejs 19.05.2018 02:53

Поигрался в Firefox, в нем наоборот класс проигрывает в два раза, т.е. датасет однозначно выигрывает. Хотя при итерации в 1 млн. в 3 раза быстрее класс, а не датасет. О, божечки... В общем, можно использовать датасет как компромис и не заморачиваться. Спасибо большое, разобрался.


Часовой пояс GMT +3, время: 20:18.