четыре data() на пути к минотавру
вторник.
вторник – это в первую очередь волшебство квин-амана.
в каком-то смысле, вторник именно чудом квин-амана лучше понедельника.
чудом квин-амана, и еще тем, что по вторникам b. patisserie открыта,
в отличие от понедельника, а там самые лучшие квин-аманы в мире.
в Гугле СФ сегодня совершенно замечательные халявные клубнично-ревеневые квин-аманы из firebrand.
с такими очень приятно не торопясь попивать кофе с видом на Bay Bridge,
– и читать код.
по вторникам я люблю читать код.
бывает, выберешь I’m feeling lucky строчку, скажем пусть из публичного ну вот
например эту одну строчку –
memset(data->data()->data()->data(), 0, data->data()->data()->length());
привяжешь к ней ниточку от клубка, что Ариадна дала, вдохнёшь поглубже, –
и пошел разматывать, в лабиринт.
чем удобны современные языки со статической типизацией и виртуальными функциями,
так это тем, что статическая типизация никоим образом не помогает предугадать, что нас тут ждет за поворотом.
поэтому никаких спойлеров, осторожно крадёшься вперёд, как Тесей в лабиринте,
вся надежда только на то, что вот это повторенное дважды заклинание data->data()->data()
взывает
оба два раза к одному и тому же объекту, чтобы взять у него ->data()
и ->length()
.
а то ведь у заклинаний иногда случаются гистерезис и side effects,
замаскированные под невинное кэширование в mutable или сразу в статическую переменную в функции,
но мы-то видели эти невинные многопоточные кэши,
– и тогда волосы шелковятся по всей седой длине.
это если конечно разматывать нить Ариадны вперед, туда, где темно, как предостерегал великий Брюсов.
можно – и зачастую намного познавательнее – разворачивать ее вглубь, во времени, потому что иначе никогда
не найти ответа на вопрос “зачем”.
зачем на самом деле Ариадна (дочь Миноса и Пасифаи) помогает Тесею победить Минотавра,
ведь Минотавр, на секундочку, – Ариадны единоутробный брат.
и тогда начинаешь крутить вот это data->data()->data()->data()
не по ссылкам и иерархиям классов,
а по истории git/svn/P4 коммитов, бранчей, мерджей и blame.
и тогда внезапно вместо обычной фальшивой черепицы ложного ООП и некоторой ленности ума, перед нами вдруг встает история взлета и падения webkit и blink, в лицах, в карьерном росте, со ссылками на линкедин, реструктуризациями, OWNERами и переходами из одной компании в другую.
тут тебе и битва браузеров, и невнятная позиция Мозиллы, и стандарты туда-сюда, и человеческие судьбы.
иногда прямо диву даешься, когда понимаешь, что вот пришел этот человечек Oliver Hunt
в октябре 2006 года в Apple, сразу после получения магистра с отличием, – и уже через полтора года, 22 февраля 2008 года влепил вот это самое
memset(data->data()->data().data(), 0, data->data()->length())
прямо в вебкит,
как часть работы по поддержке HTML5 Canvas.getImageData
API: это было время когда первый айфон уже вышел, а второй ещё нет, и у сафари не было ни copy-paste, ни табов.
в такие мгновения важно не дать себе поддаться гипнозу бездумного следования за нитью, а остановиться и вспомнить тот далекий день дождливым февралем 2008 года.
это была пятница, 22 число.
я неделю как приехал в СФ, бодро шёл по списку эйфорической сбычи мечт, и не мог не потащить @sim0nsays
слушать Euge Groove
в тот самый Yoshi’s Oakland.
и я знал, что едем в общем-то посмотреть лишь на сцену, – но на самую, на самую дорогую сцену, вот что!
легендарные там лежат доски на этой сцене, и каждая скрипит о такой горячей минувшей жизни,
о такой страстной вере в свой подвиг, в свою истину, в свою борьбу и в свой джаз,
что я, знаю заранее, – паду на сцену и буду целовать эти доски и плакать над ними.
а в субботу мы опять же вдвоем с Семеном поехали смотреть “эту вашу долину” и гулять под дождем
по теперь такому родному двору Google, где Т-рекс, Чарлиз и Йошкиз;
и потом мы кругом проехались неподалеку от Apple, но вроде так и не зашли в него,
а то скорее всего и нарвались бы на Oliver Hunt,
который в те весенние выходные продолжал выдывать на гора
тесты, тесты, тесты, тесты,
и во всех – вот эти замечательные последовательности data()->data().data()
.
но можно разворачивать нить и не вперед во тьму лабиринта,
и не вглубь во времени, – а вбок,
смотреть ревьюеров, и что они еще писали, и как росли, и что еще зашипали.
потому что только так можно понять внутренний конфликт, что раздирал пять лет Sam Weinig,
который был сначала software engineerом (и ревьюил эту самую data->data()->data().data()
),
потом четыре года спустя в 2012 стал менеджером, –
а потом через пять лет опять инженером.
и хоть наша строчка и дошла до поворотного 2012 года с минимальными изменениями:
// 5 января 2009 года:
// CanvasPixelArray performance is too slow. This devirtualisation improves performance by 1.5-2x
memset(data->data()->data(), 0, data->data()->length());
// 21 января 2009 года:
// Recent changes to the ImageData.idl broke non-JSC bindings. This change reintroduces the CanvasPixelArray.
memset(data->data()->data()->data(), 0, data->data()->data()->length());
фактически вращаясь вокруг цепочки data data data data, в 2012 году в жизни строчки и Сэма наступили радикальные изменения.
в эту строчку (и в целом в весь вебкит) стремительно ворвался
хром.
и вот уже 24 апреля 2012 года Kenneth Russell из Гугла одним движением превращает эту строчку в
data->data()->zeroFill();
а Sam Weinig проходит инициацию и на пять лет становится менеджером.
хром всё активнее разрывает вебкит на вебкит 2.0 и блинк,
а я в это время в далеком 2012 как раз заканчиваю мою четвертую неделю в Гугле,
безмятежно радуясь всяким первым:
[Achievements unlocked]
- First code review at Google
- First discussion of work-related matters with partners: people outside Google know what I’m working on!
я, впрочем, уже подозреваю, что мой внутренний achievement unlocked на следующей неделе будет уже не про Хром, а про Андроид ОС, который ворвётся на сцену ещё более стремительно:
[Achievements unlocked]
- First successfully LGTM’d code review at Google
- First encounter with Android team
но мы отвлеклись.
итак, data->data()->data()->data()
превратилась в data->data()->zeroFill()
,
и любой опытный разработчик сразу заподозрит здесь
поворот на 90 градусов.
это грубо говоря такая AoS -> SoA трансформация, только в голове у отладчика, когда длинная горизонтальная цепочка в одной строке заменяется на вертикальную портянку в крэшстеке.
посмотрим что такое zeroFill()
.
хм, это всего лишь
void Uint8ClampedArray::zeroFill()
{
zeroRange(0, length());
}
так что возможно опасения и напрасны.
ну я zeroRange
?
это просто
bool zeroRange(unsigned offset, size_t length)
{
return zeroRangeImpl(offset * sizeof(T), length * sizeof(T));
}
вот видите, ничего страшного, а zeroRangeImpl
так и совсем тривиален
bool ArrayBufferView::zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength)
{
if (byteOffset > byteLength()
|| byteOffset + rangeByteLength > byteLength()
|| byteOffset + rangeByteLength < byteOffset) {
// Out of range offset or overflow
return false;
}
char* base = static_cast<char*>(baseAddress());
memset(base + byteOffset, 0, rangeByteLength);
return true;
}
и пока вы думаете, правильно ли там стоят < и > и не нужен ли там ещё и =, мы видим что – да, это в принципе совсем не страшный подъем-переворот, где вместо того, чтобы лечь в горизонталь
memset(data->data()->data()->data(), 0, data->data()->data()->length())
оно ложится с аккуратным читаемым вертикальным крэшстеком
memset
zeroRangeImpl
zeroRange
zeroFill
createEmptyImageData
@Zeux:
Кружочки упали дважды на этом треде за последний час
Надеюсь не в memset.
@aruslan:
и то правда.
я собственно хотел о Федре рассказать, с которой Тесей в конечном итоге
прямо с острова на корабля и убежал.
Федра, единоутробная сестра Минотавра и шаловливая младшая сестренка Ариадны,
просто за компанию на паруснике решила с сестрой, Тесеем и командой матросов покататься,
и оказалась в конечном итоге совсем не проста.
но это конечно нужно смотреть не вдаль, не вглубь, не вбок,
– а вверх, на тех кто вызывает и как часто.
и тогда это будет уже совсем другая история, с падением Икара, внезапным пейпалом и предательством Мозиллы.
а сейчас я пойду спокойно поужинаю – и домой. моя фича в проде дошла до 50% в prod ramp без спецэффектов в амортизированном константном времени,
ура, товарищи, ура!