Закон Мура продолжает действовать в той формулировке, в которой его сформулировал сам Гордон Мур: количество транзисторов на кристалле увеличивается в 2 раза каждые два года. Всё остальное — журналистские байки.
“Законы Мура”
Мы уже познакомились с тремя “законами Мура”, имеющими авторство самого Гордона Мура, и ещё одним – от Дэвида Хауса. Вообще же, известен следующий (возможно, неполный) список формулировок этого закона:
1.1 – “наиболее выгодное число транзисторов на кристалле удваивается каждый год”
1.2 – “число транзисторов в производимых чипах удваивается каждые два года”
1.3 – “технологически возможное число транзисторов на кристалле удваивается каждые два года”
2.1 – “производительность МП удваивается каждые 18 мес.”
2.2 – “тактовая частота МП удваивается каждые 18 мес.” (т.к. некоторые вообще не разделяют понятия “производительности” и “тактовой частоты”, иногда закон Мура цитируется в предыдущей форме, а для его иллюстрации приводятся графики роста тактовой частоты МП)
2.3 – “вычислительная мощность компьютера удваивается каждые 18 мес.” (в рассмотрение добавляется программное и аппаратное обеспечение)
2.4 – “доступная вычислительная мощность удваивается каждые 18 мес.” (применительно к человеку/организации/человечеству, т.е. не ограничиваясь одним компьютером)
3.1 – “плотность транзисторов на чипе удваивается каждые 18 мес.” (крайне распространённая формулировка, явно противоречащая идее Мура, который рассматривал число транзисторов на ИС в целом)
3.2 – “вычислительная мощность, доступная за $1, удваивается каждые 18 мес.” / “цена одного MIPS-а падает вдвое каждые 18 мес.” (в рассмотрение вводится рынок)
3.3 – “стоимость чипа падает вдвое каждые 18 мес.” (самая размытая – неясно, что считать “тем же самым” либо “таким же” чипом через 18 мес.)
3.4 – “ёмкость памяти/жёстких дисков удваивается каждые 18 мес.” / “цена за 1Мб падает вдвое каждые 18 мес.” (хотя вовсе не о ИС, по-прежнему называется именем Мура)
В первую группу вынесены формулировки Мура, во вторую – развитие его идей другими, в третью – явно несоответствующие его идеям формулировки. Формулировки второй группы вводят в рассмотрение, кроме самих транзисторов на кристалле, их функцию, тем самым сужая поле исследования от ИС вообще до конкретно МП. При этом прямой связи между числом транзисторов на кристалле МП и его производительностью нет вообще: RISC-МП имеют меньше транзисторов, чем CISC-МП, при зачастую большей производительности; МП, программируемые на микрокоде, имеют больше транзисторов, чем с заложенной в схему программой, при меньшей производительности (но при этом могут занимать меньше места, потому что микропрограмма упаковывается плотнее, чем логика схемы). Третья группа формулировок имеет общим с идеями Мура только экспоненциальный рост какой-нибудь характеристики – другими словами, под “законом Мура” подразумевается целый ряд мало связанных тенденций. В общем же, многочисленные его формулировки сходятся лишь в одном: каждые один-два года что-нибудь, да удваивается.
Возможно, спикер не ставил себе задачей объяснить материал на уровне восьмилетнего ребенка? Каждой аудитории нужен свой уровень упрощения. Это уровень МФТИ, на сколько я понял. Но даже здесь нет ничего сложнее школьной программы, так что наезд считаю необоснованным.
Спикер, конечно, иногда не совсем внятно объясняет, но думаю, тут проблема аудитории. Мы на видео слышим только то, что он говорит в микрофон-петличку, но, судя по всему, там даже на первых рядах сидят люди, которые не стесняются разговаривать в голос. Будь я на месте спикера, просто сказал бы, что раз вам не интересно, я заканчиваю, всем спасибо. И был бы неправ, конечно. Но тут он стойко держит оборону.
WebAssembly + WebGL в теории позволяют уже сейчас делать свои движки на любой технологии. Правда, пока это приходится делать через костыли, но, думаю, в будущем можно полностью избавиться от js-загрузчика. Но у меня есть подозрение, что, если это случится, то мы окажемся в той же ситуации борьбы между конкурирующими фреймворками для рендеринга. Сначала была война браузеров, сейчас война js-фреймворков, а будет война фреймворков для рендеринга. В итоге, победят несколько фреймворков от корпораций типа Google/Apple/Microsoft, и мы окажемся в той же ситуации, что сейчас, только вместо JS будет зоопарк из разных языков и технологий.
Ну сами подумайте, что проще для отладки: написать printf (Console.WriteLine, или ещё какие аналоги в разных языках), или создать файл и писать в него логи? А если приложение на миллион строк, и надо отследить взаимодействие между разными компонентами? Делать синглтон-логгер, который будет писать в файл? Во-первых, зачем мне это, если есть консоль. Во-вторых, зачем мне городить какие-то дополнительные сущности, если потом их надо будет удалять. Ну и в-третьих, если приложение многопоточное, то придётся пилить велосипед для синхронизации записи в файл. А в консоли эти проблемы решены изначально.
Техническую литературу должен переводить специализированный переводчик со знанием предметной области. Если это не так, я бы не стал покупать такие книги.
Бывают неприятные случаи, когда приходится хакать. Для этих случаев есть рефлекшены.
Согласен, бывают. Но за всю мою 12-летнюю практику разработки софта мне лишь однажды пришлось хакнуть чужой софт через рефлекшн, и то лишь из-за того, что библиотека отрисовки графиков, которую использовали в моем проекте, не поддерживалась уже больше 5 лет, да и контора та давно закрылась.
Но мы всё же говорим о высоком. О языковых концепциях, и всё такое.
1) Если не указано обратного, по умолчанию считается, что код не предназначен для вызова в многопоточном режиме. Поэтому, вы можете принимать на вход UnmodifiableList, не боясь, что он изменится извне. Если он изменяется, то тот программист, что вызывает ваш метод, сам дурак, что не смог предоставить стабильную коллекцию, это не ваша проблема.
2) Ваша реализация похожа на грабительство — Вы отбираете массив у вызывающего объекта. Это антипаттерн.
3) На самом деле, ImmutableList-ы в большинстве библиотек построены на основе сбалансированных деревьев, поэтому, изменение листа проходит за O(log(N)).
4) «Можно считать, что посыл исходной статьи «неизменяемых коллекций в Java не будет» ошибочен.»
На основе Вашей статьи такого вывода сделать нельзя. Вы придумали кривой велосипед, который никто в здравом уме не примет за стандарт. Поэтому, изначальный посыл автора статьи остаётся актуальным.
Это всё происходит из-за того, что JVM не знает, какие объекты изменяемы, а какие нет. Из-за этого, GC обязан пройти по всем объектам, чтобы понять, какие из них ещё живы (классический Mark and Sweep + текущие модификации). В языках типа Haskell, которые заточены на работу с неизменяемыми данными, GC работает совсем по-другому: если он видит корневой объект, и знает, что этот объект immutable, он не будет проходить по дереву, т.к. и так понятно, что дочерние объекты тоже immutable. .NET сейчас тоже вводит т.н. record types, или readonly structs. Когда-нибудь, возможно, подтюнят и GC, чтобы не обходил всё дерево, если видит, что структура readonly.
Возможно, и до джавы дотянется тренд.
Что за контракт такой?
Есть такое понятие: контракт класса/интерфейса.
Обычно под контрактом подразумевается публичный контракт, хотя есть и контракты для дочерних классов, для классов внутри одного пакета, и ещё много разных вариантов.
Так вот, публичный «контракт» — это, условно, API класса. Когда класс говорит:
у меня есть метод Foo, который на вход принимает SomeWeakInterface, то это контракт.
А когда этот класс говорит, что метод Foo теперь принимает SomeStrongInterface, где SomeStrongInterface наследуется от SomeWeakInterface, то это называется «усиление контракта».
Давайте начнём сначала и забудем ту дискуссию в соседней ветке. Вы можете привести какие-то доказательства жесткой просадки скорости? Есть какие-то статистические данные?
Кроме того, Вы, похоже, не поняли того, о чём сказал math_coder. Он не об Immutable объектах, а об усилении контракта.
Да я уж понял, что вы больше про развитие стартапов, а не про программирование…
Извините, если не прав. Но с вашей стороны вообще никакой аргументации нет.
Не надо локов. Все операции делаются через Interlocked.(Compare)Exchange, а значит, нет дедлоков. Я вообще забыл этот термин уже. Считаю, это плюс. Минус — memory footprint и время на GC. Поэтому, умные разработчики совмещают оба подхода.
Неизменяемые типы гораздо удобнее в использовании в многопоточных приложениях. Меньше багов — дешевле поддержка. А хорошие программисты сами решат, где им лучше использовать (im-)mutable коллекции.
Ну мы же говорим про программирование, а не про то, как можно хакнуть систему. Если разработчики API опустились до того, чтобы кастить интерфейсы к конкретной имплементации (это должно быть уголовно наказуемо), то что им стоит через рефлекшн изменить private поля ImmutableList'а и добавить туда свой элемент?
Конечно, UnmodifiableList — более слабая абстракция, чем ImmutableList, но, учитывая накладные расходы и здравый смысл разработчиков, она всё же имеет место быть. Как уже было отмечено выше, в .NET-е уже давно есть IReadOnlyList, а относительно недавно появился и IImmutableList, и они отлично уживаются вместе, и никакие API не требуют строго IImmutableList на входе — чаще всего, ограничиваются IReadOnlyList (или ещё более ослабляют контракт до IReadOnlyCollection или даже до IEnumerable). Если вы не доверяете тому API, что вызываете, то всегда можно передать туда не ArrayList, а ImmutableList, и тогда этот злой API не сможет его скастить в List.
Допустим, у вас есть класс A, который часто модифицирует некую коллекцию и иногда вызывает API для подсчёта статистики по этой коллекции. По хорошему, API должен гарантировать неизменность коллекции. Для этого, на вход следует принимать UnmodifiableList, чтобы декларировать неизменяемость.
ImmutableList в данном случае будет оверхэдом с точки зрения класса A, т.к. приводит к копированию массива или перестроению дерева (в зависимости от внутренней реализации ImmutableList-а) при каждой модификации коллекции.
cs.usu.edu.ru/study/moore
Спикер, конечно, иногда не совсем внятно объясняет, но думаю, тут проблема аудитории. Мы на видео слышим только то, что он говорит в микрофон-петличку, но, судя по всему, там даже на первых рядах сидят люди, которые не стесняются разговаривать в голос. Будь я на месте спикера, просто сказал бы, что раз вам не интересно, я заканчиваю, всем спасибо. И был бы неправ, конечно. Но тут он стойко держит оборону.
Извините, а где здесь вызов? Тут вообще нет ни одной строчки Javascript-кода.
Согласен, бывают. Но за всю мою 12-летнюю практику разработки софта мне лишь однажды пришлось хакнуть чужой софт через рефлекшн, и то лишь из-за того, что библиотека отрисовки графиков, которую использовали в моем проекте, не поддерживалась уже больше 5 лет, да и контора та давно закрылась.
Но мы всё же говорим о высоком. О языковых концепциях, и всё такое.
2) Ваша реализация похожа на грабительство — Вы отбираете массив у вызывающего объекта. Это антипаттерн.
3) На самом деле, ImmutableList-ы в большинстве библиотек построены на основе сбалансированных деревьев, поэтому, изменение листа проходит за O(log(N)).
4) «Можно считать, что посыл исходной статьи «неизменяемых коллекций в Java не будет» ошибочен.»
На основе Вашей статьи такого вывода сделать нельзя. Вы придумали кривой велосипед, который никто в здравом уме не примет за стандарт. Поэтому, изначальный посыл автора статьи остаётся актуальным.
Возможно, и до джавы дотянется тренд.
Есть такое понятие: контракт класса/интерфейса.
Обычно под контрактом подразумевается публичный контракт, хотя есть и контракты для дочерних классов, для классов внутри одного пакета, и ещё много разных вариантов.
Так вот, публичный «контракт» — это, условно, API класса. Когда класс говорит:
у меня есть метод Foo, который на вход принимает SomeWeakInterface, то это контракт.
А когда этот класс говорит, что метод Foo теперь принимает SomeStrongInterface, где SomeStrongInterface наследуется от SomeWeakInterface, то это называется «усиление контракта».
Кроме того, Вы, похоже, не поняли того, о чём сказал math_coder. Он не об Immutable объектах, а об усилении контракта.
Извините, если не прав. Но с вашей стороны вообще никакой аргументации нет.
Конечно, UnmodifiableList — более слабая абстракция, чем ImmutableList, но, учитывая накладные расходы и здравый смысл разработчиков, она всё же имеет место быть. Как уже было отмечено выше, в .NET-е уже давно есть IReadOnlyList, а относительно недавно появился и IImmutableList, и они отлично уживаются вместе, и никакие API не требуют строго IImmutableList на входе — чаще всего, ограничиваются IReadOnlyList (или ещё более ослабляют контракт до IReadOnlyCollection или даже до IEnumerable). Если вы не доверяете тому API, что вызываете, то всегда можно передать туда не ArrayList, а ImmutableList, и тогда этот злой API не сможет его скастить в List.
ImmutableList в данном случае будет оверхэдом с точки зрения класса A, т.к. приводит к копированию массива или перестроению дерева (в зависимости от внутренней реализации ImmutableList-а) при каждой модификации коллекции.