Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 08.01.2013, 22:21
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

V8 нахождение деоптимизаций
Чтобы понимать, о чём суть, можно ознакомиться с этой статьёй.

Презентация об оптимизации компилирования JavaScript в V8

Думаю, все знают о том, как управлять качеством компилируемого JavaScript - наверняка это относится не только к V8, но и к FireFox'овским компилятором, которые он меняет через неск. версий (сейчас я про JIT компиляторы).

Вкратце, всё сводится к тому, чтобы как можно более статично писать код - т.е. не использовать разные типы для одной переменной, не добавлять новые свойства к объекту и т.д. ... короче, чтобы получить действительно быстрый JavaScript, нужно как-то особенно писать.

Тут то и возникает проблема. Вот вроде бы ты и написал, как "надо". Как теперь проверить, деоптимизируется ли функция? Вариант с бенчмарками отпадает, как самый примитивный.


Я немного пощупал V8 (точнее, Chrome, ну да ладно) на предмет логирования его действий при обработке моего скрипта.

Всё свелось к простейшему созданию особого ярлыка для Chrome, и перетаскиванию HTML-файла со скриптом на этот ярлык (я пока на виндовсе ) :
Код:
C:\Users\LOL\AppData\Local\Google\Chrome\Application\chrome.exe --no-sandbox 
--js-flags="--logfile=%t.log --trace-opt --trace-deopt  --noprof-lazy --prof-auto --log-gc"  
--incognito
Все эти флаги были бережно нагуглены:
Profiling Chromium With V8
Profiling Chromium With V8 №2

после этого в папке с chrome.dll появился файл лога, содержащий какие-то записи сумашедшего летописца.

Вроде я указал, что мне нужно записывать , но поиск по файлу ничего путёвого, кроме какого-то левого профилирования, не выдал.

Лог сам весит 211 кб Первое упоминание о моём файле аж на 656'й строке.

Код:
code-creation,Function,0x369363a0,7992," file:///E:/Max/melanim/dist/mel-anim.compiled.js:5",0x26828704,~
code-creation,Script,0x369382e0,208,"file:///E:/Max/melanim/dist/mel-anim.compiled.js",0x268287a8,~
Наверное, это начало разбора главного большого замыкания... интересно, что означают эти записи ?

ещё немного бреда :
Код:
code-creation,LoadIC,0x3693d660,98,"prefix"
code-creation,LoadIC,0x3693d660,98,"prefix"
code-creation,LoadIC,0x3693d6e0,98,"lowPrefix"
code-creation,LoadIC,0x3693d6e0,98,"lowPrefix"
code-creation,KeyedLoadIC,0x3693d760,110,"animation"
code-creation,KeyedLoadIC,0x3693d760,110,"animation
Что такое LoadIC? А KeyedLoadIC?

особенно интересны эти моменты :
Код:
code-creation,LazyCompile,0x36955160,232,"type.array file:///E:/Max/melanim/dist/mel-anim.compiled.js:73",0x268269a4,~
code-creation,LazyCompile,0x36955260,544,"type.array file:///E:/Max/melanim/dist/mel-anim.compiled.js:73",0x268269a4,*
Что означают разные символы на концах строк (~ и *)? что такое LazyCompile?

Короче, куча вопросов, и ответов нет. Попытки гугления при водят только к непонятной документации.

Я хотел найти deopt'ы. Где они ?) Кто-нибудь вообще занимался этим?
Ответить с цитированием
  #2 (permalink)  
Старый 08.01.2013, 22:32
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Пока нашел только это http://qps.ru/y5SKO
Ответить с цитированием
  #3 (permalink)  
Старый 08.01.2013, 22:47
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Излишняя оптимизация зло, которое может превратить код в какашку
__________________
kobezzza
code monkey
Ответить с цитированием
  #4 (permalink)  
Старый 08.01.2013, 23:32
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Deff Посмотреть сообщение
Пока нашел только это http://qps.ru/y5SKO
Я это видел. К сожалению, в этих логах я не нашёл ничего полезного

Сообщение от kobezzza Посмотреть сообщение
Излишняя оптимизация зло, которое может превратить код в какашку
Думаешь? хз хз ... в моём прокте важна каждая наносекунда - именно из-за неё может появиться тормоз и снизиться ФПС, ради чего всё затевалось.

Кстати, код для оптимизаций меняется не так сильно и совсем не уродуется :
Parser.prototype.parse = function (s) {
  var length = '', i = 0;
  while (i < s.length) {
    if (s[i] == '\u0000') {
      length = Number(length);
      this.emit('data', s.substr(i + 1, length));

-      s = s.substr(i + 1 + x);
-      i = 0; 
+      i += length + 1;

      length = '';
    } else {
      length += s[i++];
    }
  }
};

(я думаю, понятно, что за плюсы и минусы слева пример из презентации)

Самое главное - обьяснить компилятору, что тут именно тот привычный типизированный быстрый код какого-нибудь C++, написанный на JavaScript;

Всё, что я хочу - прочитать эти сказки о типизации, рассказанные компилятором в отношении моего кода.
Ответить с цитированием
  #5 (permalink)  
Старый 08.01.2013, 23:39
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

melky, если оптимизация реально нужна, то конечно нужно её делать, я лишь хотел сказать, что прочитав статью не нужно всем дружно бросаться переписывать наш код под каждый интерпретатор и фапать на мистический наносекунды

Цитата:
Кстати, код для оптимизаций меняется не так сильно и совсем не уродуется
В твоём случае да, но я имел ввиду скорее общий случай оптимизаций (будь то алгоритмическая и т.д.), к примеру я переписал для будущей версии своего Collection метод extend (интерфейс как в jQuery) с классической реализации рекурсией на рекурсию развёрнутую в массив: оптимизация в среднем в 2.5 раза, но смысл кода реально понять сложнее.

Collection.extend = function (deep, target, var_args) {
	deep = deep || false;
	target = target || {};
	var aLength = arguments.length,
		
		aEl, key,
		src, copy,
		copyIsArray,
		
		i = 1, j,
		
		stack = [],
		level,
		
		last, lastEl;
	
	// Внешний цикл по расширяющим аргументам
	while (++i < aLength) {
		if ((aEl = arguments[i])) {
			// Цикл для эмуляции рекурсии
			while (aEl) {
				level = [];
				
				// Цикл по свойствам объекта
				for (key in aEl) {
					src = target[key];
					copy = aEl[key];
					
					// Защита от бесконечного копирования
					if (target === copy) { continue; }
					
					// Рекурсивное копирование свойств
					// (рекурсия развёрнута)
					if (
						deep && copy
						&& ((copyIsArray = Array.isArray(copy)) || typeof copy === 'object')
					) {
						// Если копируемое свойство - массив
						if (copyIsArray) {
							copyIsArray = false;
							clone = src && Array.isArray(src) ? src : [];
						
						// Если копируемое свойство - объект
						} else {
							clone = src && typeof src === 'object' ? src : {};
						}
						
						// Запоминаем вложенность, чтобы в дальнейшем к ней вернуться
						level.push({
							target: target,
							clone: clone,
							
							aEl: aEl,
							copy: copy,
							
							key: key
						});
					} else {
						target[key] = copy;
					}
				}
				
				// Если на уровне имеются вложенности,
				// то добавляем новый уровень в стек и
				// проиводим сдвиг в крайне правый элемент нового уровня
				if ((last = level.length)) {
					stack.push(level);
					
					last = level[last - 1];
					// Ставим флаг, что элемент учавствует в обходе
					last['__COLLECTION_TMP__'] = true;
					
					// Устанавливаем новую точку отсчёта
					target = last.clone;
					aEl = last.copy;
					
				// На уровне нет вложенностей
				} else if ((last = stack.length)) {
					j = stack.length;
					while (j--) {
						lastEl = stack[j][stack[j].length - 1];
						
						// Если звено не имеет детей и уже было использовано,
						// то удаляем крайне правый элемент и сдвигаем позицию обхода
						if (lastEl['__COLLECTION_TMP__'] && !stack[j + 1]) {
							lastEl.target[lastEl.key] = target;
							target = lastEl.target;
							aEl = lastEl.aEl;
							stack[j].pop();
							
							// В звене не осталось элементов,
							// значит его можно удалить
							if (!stack[j].length) {
								stack.pop();
							}
						
						// Если первое условие не верно,
						// значит продолжать цикл нет смысла
						} else {
							break;
						}
					}
					
					// Устанавливаем новую позицию обхода
					if ((last = stack.length)) {
						last = stack[last - 1];
						lastEl = last[last.length - 1];
						lastEl['__COLLECTION_TMP__'] = true;
						
						target = lastEl.clone;
						aEl = lastEl.copy;
					}
				}
				
				// Операция закончена
				if (!stack.length && !level.length) {
					break;
				}
			}
		}
	}
	
	return target;
};
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 09.01.2013 в 00:21.
Ответить с цитированием
  #6 (permalink)  
Старый 09.01.2013, 00:42
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от kobezzza
В твоём случае да, но я имел ввиду скорее общий случай оптимизаций (будь то алгоритмическая и т.д.), к примеру я переписал для будущей версии своего Collection метод extend (интерфейс как в jQuery) с классической реализации рекурсией на рекурсию развёрнутую в массив: оптимизация в среднем в 2.5 раза, но смысл кода реально понять сложнее.
Согласен, сначала нужно оптимизировать алгоритмически, а потом заниматься этими изысками. Так и сделаю, отложу муравьёв на потом.

Имхо следует в dev-версии оставлять самый понятный код - т.е. рекурсию. Есть скрипты для разворачивания рекурсии в цикл ... я видел его, если мне не показалось, могу поискать, любопытная вещица.
Ответить с цитированием
  #7 (permalink)  
Старый 09.01.2013, 00:54
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Сообщение от melky Посмотреть сообщение
Имхо следует в dev-версии оставлять самый понятный код - т.е. рекурсию.
Рекурсия в контексте моего Collection плодит много лишних тормозов, а так я тока за неё, т.к. очень простое и элегантное решение.

Сообщение от melky Посмотреть сообщение
Есть скрипты для разворачивания рекурсии в цикл ... я видел его, если мне не показалось, могу поискать, любопытная вещица.
У меня как раз так и делается: рекурсия раскладывается в простой массив и обходится циклом (т.е. стек контекстов исполнений функции эмулируется простым массивом), просто мне почему то больше нравится выражение "развёрнуто в массив", нежели "развёрнуто в цикл", хотя мб я не прав и нужно учиться говорить понятнее
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 09.01.2013 в 01:42.
Ответить с цитированием
  #8 (permalink)  
Старый 09.01.2013, 01:09
Аватар для Gozar
Отправить личное сообщение для Gozar Посмотреть профиль Найти все сообщения от Gozar
 
Регистрация: 07.06.2007
Сообщений: 7,504

Сообщение от melky
Презентация об оптимизации компилирования JavaScript в V8
Я бы скорее давал ссылку на JavaScript глазами JIT-компилятора, Вячеслав Егоров
Тем, кто не в курсе про jit будет гораздо более понятно, нежели текстовый срез из доклада.

Ну и линк на слайды: http://s3.mrale.ph/TechForum2012.pdf
__________________
Последний раз редактировалось Gozar, Сегодня в 24:14.

Последний раз редактировалось Gozar, 09.01.2013 в 18:51.
Ответить с цитированием
  #9 (permalink)  
Старый 09.01.2013, 18:00
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Gozar Посмотреть сообщение
Я бы скорее давал ссылку на JavaScript глазами JIT-компилятора, Вячеслав Егоров
Тем, кто не в курсе про jit будет гораздо более понятно, нежели текстовый срез из доклада.
спасибо, поглядим.
Ответить с цитированием
  #10 (permalink)  
Старый 10.01.2013, 05:20
Профессор
Посмотреть профиль Найти все сообщения от godofjavascript
 
Регистрация: 11.12.2012
Сообщений: 265

Gozar,
спасибо
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нахождение позиции курсора мыши Severtain Общие вопросы Javascript 5 30.10.2013 16:35
Функция match - нахождение ссылок new_forward Общие вопросы Javascript 6 21.06.2012 21:19
Нахождение активного обекта и извлечения значения! Gerg007 Общие вопросы Javascript 2 17.06.2012 16:18
нахождение положения объекта bohdan Общие вопросы Javascript 2 01.03.2012 01:48
нахождение блока script HelpeR Events/DOM/Window 3 22.09.2010 14:40