Later Ctrl + ↑

Гамбург. Неделя вторая

Перелет.
Неделя первая.

Когда я первый раз говорил, что молодежи мало, я ошибался. Это все район такой, в котором я жил. Молодежи много, но она сосредоточена в других местах. Одно из основных ночных тусовочных мест — репабан. Казино, секс шопы, клубы, публичные дома: всего хватает. И оно тебя тоже хватает и куда-то пытается утащить. Я был в будний день, достаточно спокойно. В пятницу же народа — толпа, так что протолкнуться сложно.

Фонтан по пути в офис

Погуляли по центру.

Старых зданий множество: их хранят и оберегают.

Вид зданий приятен.

Объем мелких деталей впечатляет.

Хотя есть район, который выглядит не очень. То ли экспериментальный, то ли еще что. Скучные бизнес центры

Летучая мышь.

Ее подруга: летучая жаба

Вид от туда

Вид от сюда

Спорткрар на батарейках

Из автопрома по городу ездят кабриолеты, манипусенькие машинки, городские автобусы. Другие представители редки.

Типичные домики недалеко от отеля

Велосипедная дорожка и парковка

А вот так выглядят дворики в многоэтажных домах

И аллеи рядом с ними

В метро реклама на ломанном русском зовет в Москву

Да и рекламы в метро хватает. Стенд выглядит как стена комнаты подростка-рокера.

Везде стоят урны для раздельного сбора мусора

четырехсторонние.

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

Вторая неделя подходит к концу, а это значит, что я еду в другой город — Кайзерслаутерн. Вперед на юг.

Поездка проходит с пересадками. Первый поезд идет 4 часа. Мне попались в соседи мужики. Назвал бы их рабочими. Всю дорогу пили пиво, заедали конфетами и громко разговаривали. Достали карты, предложили мне «give your dollars». Из уважения, конечно. Рубились на деньги. Двое сидели спиной к окну, в котором отражались их карты. Не я один это заметил, поэтому те ребята проиграли.

При пересадке встретил поезд «Москва-Берлин-Париж». Красные точки на окнах — места куда надо бить, чтобы окно разбилось.

Бонус: уличные музыканты.

Что почитать. Ссылки 13.10

Скопилось интересного на поделиться:

  1. Ограничений не существует. История про то, что ограничения накладывает общество, и не всегда они разумны. Особенно когда дело касается достижения вашей цели. Валера рассказывал, как удивлялись далеко не последние мира сего, когда принимали эту фразу.
  2. Результаты и цели. Мысль про то, что результат есть набор целей, но на его исход по сути повлиять нельзя. Можно только увеличить вероятность наступления. Абсолюта нет, ребята.
  3. Понимание и умение. Чтобы сделать, не достаточно только понимать, не достаточно уметь. Надо и то и другое. При ограничениях мозга физических, дорога в более глубокую специализацию.
  4. Идеи и бизнес идеи. Про подмену понятий. Яркий пример «своя сорочка к телу ближе».
  5. Школа рабства и послушания. Больной вопрос образования.

Гамбург. Неделя первая

Перелет.

Очень мало молодых. Я действительно имею в виду мало. Всего 5% из встреченных. Не знаю, может они учатся или не выходят на улицы. При том они или негры, или явные хипстеры (привет, Глеб и Оксана), или очень странно наряженные, достриженные, покрашенные.

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

Какой-то парень и бездомная безумная в метро

Собачников множество. Выгуливают животных в парках (но там где не запрещено).

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

Множество велосипедистов. Для них есть специальная разметка как на дороге, так и на тротуарах. Их так много, что на светофорах для них выделен специальный знак. Повсюду припаркованы велосипеды. Из припаркованных приличная часть стоит больше, чем месяц. Колеса «вросли» в грунт и сдулись, куча листьев в багажниках, ржавчина на цепях. Но никого это не парит.

На велосипедах ездят повсеместно: на работу, перевозят грузы (кто-то вез офисный стул), развозят почту. Никого не удивляет мужичок в костюме на велике, жующий бутерброд.

Транспортная система — единая на весь город. В нее входят автобусы, трамваи, метро, паромы. Можно купить один проездной на все виды транспорта. Не надо думать какой вит транспорта удобнее выбрать, а только про то, как добраться до точки назначения.

Реклама, мусорка, почтовый ящик в метро

Отдельно про метро. Быстрое, удобное. С навигацией не возникает никаких проблем. Если знаешь как называется твоя станция, то достаточно найти метро в любой точке города, а там разберешься как добраться. В общем-то я так и поступил, когда заблудился. Как положено, в переходах метро есть забегаловки и бездомные. Или кусок старого паровоза.

Прокатился на пароме.

Вид с причала

Посмотрел на город со стороны реки.

Французский парусник выглядит устаревшим.

Строящийся концертный холл. Размеры впечатляют.

В городе есть огромный порт.

Вид на порт из парка

В районе порта (вдоль ) целый пучок ресторанчиков и кафешек, в названии каждого обязательно есть слово «рыба». Запах характерный. Ровно как и блюда.

Кафе и ресторанов невиданное разнообразие. Большинство имеют лавочки или столики на улице. Пледы, подушки под попу. Вообще улицы устроены уютно. Приятно как ходить, так и сидеть с чашкой чая.

Тут без проблем приготовят блюдо, которого нет в меню. Хотел заказать салат с мясом, его не оказалось в меню. Но это не помешало повару его приготовить. Меню в большей степени на немецком, но большинство официантов знает худо-бедно английский, и поможет с выбором блюда. Блюда огромные. Если написано, что это рыба, не стоит ожидать увидеть кильку на тарелке. При заказе мяса приносят: огромного размера мясо, картошку фри, салат, грибной соус, хлеб и пару пакетиков майонеза. Вместе с большим лимонадом все стоило 11.20 евро. Наелся, когда оставалась еще треть.

В виду того, что много используется евро в виде монеток (достоинством 1 и 2), кошельки имеют огромные отделения для мелочи. На сколько я не люблю ходить с мелочью дома, здесь приходится переучиваться. Сдача в магазинах и кафе есть почти всегда (с 50 не сразу нашлась).

Попал на день завода пятого айфона. В свободной продаже ни одного не было: все разобрали по предзаказам. Один хипстер радовался и прыгал, а работники магазина подыгрывали ему: хлопали и улюлюкали. Слишком ситуация смахивает на действие секты или какой церкви. Зато удалось потрогать айфон на стендах. Легкий, тонкий, стильный. Доставать пальцем до контролов было не проблематично. Возможно из-за краткости нашего с ним общения или отсутствия моего айфонового опыта. Цены на яблокопродукцию такие-же как у нас или чуть дешевле.

Если пройтись ночью по зоне можно встретить кроликов в стайках по 3-5 штук (или зайцев, я их не различаю). Бездомные собаки безуспешно охотятся на серых.

UPD Бонусы от Николая:
Хипстер получил айфон 5

Поездка на городском транспорте

Днепропетровск -> Киев -> Копенгаген -> Гамбург

Несколько перелетов в один день. Так как раньше не летал, мне было трудно оценить удобство устройства Днепропетровского аэропорта (вместе с ним и Киевского). В Киеве покушали вкусную пиццу, по приемлемой цене (70 грн).

Кстати, на территории вокзала всего один вид банка: «The Bank». Такое хитрое название наверняка помогает иностранцам оценить масштабы конкуренции. Этот самый банк, согласно родному законодательству не меняет гривны на валюту без предъявления паспорта. Кстати, не знаю как наоборот, но что-то подсказывает, что купить гривну за доллары или евро не оставит проблем. Одной женщине, соответственно без украинского паспорта не меняли остаток гривен. Поменяли на мой паспорт. Кстати, вся процедура (копирование паспорта, подписи на нем и еще распечатка каких-то бумажек) заняла минут 10.

Уважения со стороны служащих (девочка на терминале и охранник еже с ней) не проявили, когда мы по ошибке пошли к терминалу не в том здании аэропорта. С другой стороны в Копенгагене охранник помог с поиском терминала (правда тот, что он назвал в итоге оказался не нашим).

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

Вайфай в Киеве бесплатный, и достаточно шустрый. Автобус, который вез нас к трапу был набит битком. Но может это просто совпадение.

При полете видел как работают закрылки (кажется так называются подвижные части крыла с противоположной движению стороны). Вообще, если бы я не представлял примерно требования к безопасности самолетостроения и не знал статистику, то переживал от ненадежности конструкции на вид.

Аэропорт в Копенгагене огромен по сравнению с Киевским. И больше похож на торговый центр с магазинчиками и кафешками. Очень недешевыми, как мне кажется. 2 кофе и 2 бутерброда обошлись в 37 евро. Три яблока — в 3 евро. А сдачу выдали в датских кронах.

Вайфай бесплатен, но для того, чтобы им пользоваться надо зарегистрироваться. Не технарям абзац ниже можно пропустить Очень круто сделано: после заполнения формы регистрации (с кучей полей, кстати), тебе на 15 минут включают интернет и высылают письмо с подтверждением. При подтверждении на тебя автоматически заводится аккаунт. На него можно собирать бонусы от покупок (я не интересовался на что их можно тратить). А карточку можно забрать у информационной стойки.

Очень приятно порадовали сидения, которые уважают личное пространство. На них не будешь тереться плечом о плечо с соседом.

Иногда мимо проходят немытые тела, распространяя европейское амбре.

Из публики доминируют мужчины лет 30-40. Женщины и более молодые человеческие особи редки. Особый интерес вызывал мужичок восточной наружности. Он другому уже в сединах европейцу с восторгом рассказывал про частицы, их колебания, создание кристаллов и что-то про свет. Безумный малый. Прямо сейчас сидит слева от меня через проход и пишет что-то в большой тетради.

Через 40 минут в Гамбурге.

Про оптимизацию javascript кода (часть 2)

Первая часть с выводами.

Как говорилось в первой части, большого смысла в оптимизации повседневного кода нет. Разумеется, я не призываю писать заведомо неудачные решения. Но и особо изгалаться тоже нет смысла. В подтверждение этому привожу историю оптимизации. Сразу оговорюсь, что можно было бы, например, генерировать новую таблицу,

Задача:
случайным образом перемешать ряды в таблице. Генерировать новую таблицу нельзя, необходимо использовать существующие узлы.

Возможные оптимизации

  • Избегать использований liveCollection. А точнее: превращение liveCollection в массив. Гипотеза заключается в том, что так как liveCollection должна обновляться вместе с обновлением DOM, это приведет к дополнительным штрафам скорости. Разумеется, браузеры могут оптимизировать работу с liveCollection, но об этом еще предстоит узнать.
  • Свести к минимуму обращения к DOM-у, как удаление, так и добавление узлов. Применение documentFragment и временное удаление узла из DOM-а.
  • Использование documentFragment, как буфера для временного хранения отсортированных случайным образом рядов.
  • Удаление на время из DOM-а, элемента, который содержит в себе перемешиваемы ряды. Теоретически должно произойти уменьшение количества обращений к DOM при удалении ряда.

Из этих вариантов я составил варианты их комбинаций и написал тесты на jspref.com и прогнал через имеющиеся браузеры. Ниже находится интерпретация полученных данных.

  • Самое главное: нет подхода, который был бы самым быстрым для каждого браузера. Из этого следует следующее:
    • Оптимизируя код, не зная как он будет в последствии работать, можно сделать оптимальную версию для одного браузера, и неоптимальную для другого.
    • Изменение кода до неузнаваемости может не дать выигрыша в производительности
  • Все браузеры медленно работают с liveCollection. Для выигрыша в производительности надо преобразовывать liveCollection в массив.
  • Хрому и сафари не имеет значения, используется ли documentFragment и удаляется ли нод временно из DOM-а. Это говорит про оптимизированность методов, которые он применяет к обработке дома. Налицо несомненный плюс для пользователей, но с другой стороны есть эффект поощрения излишних DOM манипуляций со стороны непонимающих программистов (особенно, если они разрабатывают в хроме и не проверяют параллельно в других браузерах). Хотя это их проблемы.
  • documentFragment играет важную роль в ускорении работы с DOM в ие.
  • В фаерфоксе не оптимизирована работа с удаляемыми нодами. Временное удаление контейнера, содержащий удаляемыми строки, дает почти двукратное ускорение.

Итого
При работе с DOM-ом имеет смысл поменьше использовать liveCollection и побольше documentFragment. Остальные оптимизации будут давать неоднозначные результаты.

Как преобразовать массивоподобный объект в массив

В продолжение недели оптимизации.
Я знаю 2 способа превращения массивоподобных объектов (МПО) в массив. В МПО входят: объект arguments, live collection, dead collection. Первый подход — итерация и создание нового массива из элементов МПО поштучно. Второй — применение splice в контексте МПО. При иплементации функции to_array стал вопрос: какой из способов быстрее. Чтобы не гадать, написал тесты. Тесты можно посмотреть и погонять на jsperf.

Из интересного:

  • сафари6, как и опера 12.02 в 2 раза быстреe преобразует querySelectorAll() коллекцию в массив с помощью slice.
  • в хроме, сафари о опере доступ к querySelectorAll коллекциям быстрее, чем к getElementsBy и document.links.

Итого: я не вижу смысла реализовывать в to_array как итерационный подход, так и splice (который в ие8 и ниже не работает). В результате, чтобы преобразовать коллекцию в массив можно использовать следующий код:

function to_array (obj) {
	var i,
		length,
		res;

	if (Object.prototype.toString.call(obj) === '[object Array]') {
		return obj;
	}
	length = obj.length;
	res = [];
	for (i = 0; i < length; i += 1) {
		res.push(obj[i]);
	}
	return res;
}

Про оптимизацию javascript кода (часть 1)

Нижеследующее — размышления после профилирования нескольких скриптов, и поисков быстрого кода.

Все больше статей по клиентской оптимизации появляется. Но проблема в том, что практики из статей начинают применять молодые разработчики без понимания причин. Зачастую авторы статей рассказывают как они решили свою проблему.

Видел людей, которые всерьез спорят про быстрые и медленные циклы, и использование бинарных операторов для ускорения. На практике потребность в подобных манипуляциях встречается очень редко. Эти споры процветают, пишутся тесты. Правда ребята забывают, что самым узким местом клиентского JS является DOM.

При переписывании цикла на более быструю версию, кеширование переменных (для более быстрого поиска по областям видимости) скрипт можно ускорить на 5%, ну на 10%. При этом произойдет
потеря в читаемости исходного кода, его понимании.

Но ситуация с оптимизацией — палка о трех концах. Второй конец: браузерная оптимизация. Например пример двух циклов:

 // 1
for (var i = 0; i < arr.length; i += 1) {}
// 2 
for (var i = 0, length = arr.length, i < length; i += 1){}
// 3
var length = arr.length;
while (length--){}

Вторая версия чуть более многословна, но быстрее первой. Третья менее многословна, но не совсем понятна слету (проход по массиву в обратном порядке не естественен для понимания).

На практике интерпретаторы сами оптимизируют код циклов, и большой разницы в скорости отработки в современном браузере профилирование не покажет, не говоря уже о пользовательских ощущениях. Какая разница, скрипт выполнится за 10мс или 9мс.

Подобные оптимизации сработают для старых браузеров. Но тут возникает вопрос целесообразности: надо ли держать такое количество непонятного кода только для оптимизации (еще не понятно необходимой ли) работы старых браузеров. Намного лучше оставить код многословным и однозначным. Пусть оптимизируют интерпретаторы.

А вот третий конец — это DOM. Обновление одного узла в DOM-e ведет за собой каскад телодвижений со стороны браузера: обновление свойств children, parentNode, nextSibling у нод, которые «цепляются» этим изменением, обновление liveCollections, триггер repaint и reflow, очистка памяти, если использован innerHTML, то еще дополнительный парсинг текста в DOM модель. На фоне такого количества действий низкоуровневые оптимизации меркнут. Слишком просто одним лишним обращением к DOM-у свести все оптимизации на нет.

Узких мест в DOM-е множество. Самые тяжелые — обновление: добавление и удаление узлов. При том время отработки одного и того же кода зависит от общей сложности DOM дерева, максимальной вложенности, количества таблиц стилей и количества правил. Это означает, что один и тот же способ оптимизации даст различный прирост, в зависимости от сложности страницы.

Браузерные производители понимают, и со своей стороны стараются оптимизировать код движков. И тут мы наблюдаем другую интересную ситуацию: разные подходы к оптимизации дают разный прирост в разных браузерах. Чем древнее браузер, тем вероятнее, что хитрые манипуляции дадут преимущество.

Снова повторяется история с циклами: не стоит усложнять исходны код, подстраивая его под браузер. Пусть этим занимаются браузеростроители.

Я к чему веду: смысла в особой оптимизации кода нет. Самый разумный подход — написать код как есть, структурировать и сделать его читаемым и понятным. И только если профилирование покажет необходимость оптимизаций, начать именно с оптимизации работы с DOM.

Earlier Ctrl + ↓