Как перезапустить закон Мура программными методами. Ускорение софта в тысячи раз

    Профессор Никлаус Вирт был прав. Создатель языка Pascal, соавтор технологии структурного программирования, лауреат премии Тьюринга в 1995 году заметил:

    «Замедление программ происходит куда быстрее, чем ускорение компьютеров»


    С тех пор это высказывание считается законом Вирта. Он фактически нивелирует закон Мура, согласно которому количество транзисторов в процессорах удваивается примерно с 1965 года. Вот что пишет Вирт в статье «Призыв к стройному софту»:

    «Около 25 лет назад интерактивный текстовый редактор умещался всего в 8000 байт, а компилятор в 32 килобайта, тогда как их современные потомки требуют мегабайтов. Стало ли всё это раздутое программное обеспечение быстрее? Нет, совсем наоборот. Если бы не в тысячу раз более быстрое железо, то современное программное обеспечение было бы совершенно непригодным».

    С этим трудно не согласиться.

    Ожирение софта


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

    Сегодня появилась ещё одна причина ожирения софта — абстракция. И это гораздо более серьёзная проблема. Разработчики никогда не писали программы с нуля, но раньше это не вызывало осложнений.

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

    Те времена прошли.

    С появлением языков более высокого уровня, таких как Java, Ruby, PHP и Javascript, к 1995 году, когда Вирт написал свою статью, программирование стало более абстрактным. Новые языки значительно облегчали программирование и многое брали на себя. Они были объектно-ориентированными и поставлялись в комплекте с с такими вещами, как IDE и сборка мусора.

    Программистам стало легче жить, но за всё приходится платить. Чем легче жить, тем меньше думать. Примерно в середине 90-х программисты перестали думать о качестве своих программ, пишет разработчик Робин Мартин в своей статье «Никлаус Вирт был прав, и в этом проблема». В то же время началось широкое использование библиотек, функциональность которых всегда намного больше, чем необходимо для конкретной программы.

    Поскольку библиотека не создана для одного конкретного проекта, она, вероятно, имеет немного больше функциональных возможностей, чем действительно нужно. Никаких проблем, скажете вы. Однако всё накапливается довольно быстро. Даже люди, которые любят библиотеки, не хотят изобретать велосипед. Это приводит к тому, что называется адом зависимостей. Никола Дуза написал пост об этой проблеме в Javascript.

    Проблема не кажется такой уж большой, но в реальности она серьёзнее, чем вы можете подумать. Например, Никола Дуза написал простое приложение для ведения списка дел. Оно работает в вашем браузере с HTML и Javascript. Как вы думаете, сколько зависимостей оно использовало? 13 000. Тринадцать. Тысяч. Пруф.

    Цифры безумны, но проблема будет только расти. По мере создания новых библиотек число зависимостей в каждом проекте также будет увеличиваться.

    Это означает, что проблема, о которой предупреждал Никлаус Вирт в 1995 году, со временем только усугубится.

    Что делать?

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

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

    Конец закона Мура


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

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


    Эволюция транзисторов. Иллюстрация: Samsung

    Но некоторые исследователи подходят с другой стороны. Они предлагают новые системные подходы к программированию, чтобы значительно повысить эффективность будущего программного обеспечения. Таким образом, можно «перезапустить» закон Мура программными методами, как бы фантастически это не звучало в свете наблюдений Никлауса Вирта об ожирении программ. Но вдруг у нас получится обернуть эту тенденцию вспять?

    Методы ускорения программного обеспечения


    Недавно в журнале Science была опубликована интересная статья учёных из лаборатории компьютерных наук и искусственного интеллекта Массачусетского технологического института (CSAIL MIT). Они выделяют три приоритетные области для дальнейшего ускорения вычислений:

    • лучшее программное обеспечение;
    • новые алгоритмы;
    • более оптимизированное железо.

    Ведущий автор научной работы Чарльз Лейзерсон подтверждает тезис об ожирении ПО. Он говорит, что выгоды миниатюризации транзисторов были настолько велики, что на протяжении десятилетий программисты могли уделять приоритетное внимание упрощению написания кода, а не ускорению его выполнения. С неэффективностью можно было смириться, потому что более быстрые компьютерные чипы всегда компенсировали ожирение ПО.

    «Но в настоящее время для достижения дальнейших успехов в таких областях, как машинное обучение, робототехника и виртуальная реальность, потребуются огромные вычислительные мощности, которые миниатюризация уже не может обеспечить, — говорит Лейзерсон. — Если мы хотим использовать весь потенциал этих технологий, мы должны изменить наш подход к вычислениям».

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

    Во многих случаях производительность действительно можно повысить в тысячи раз, и это не преувеличение. В качестве примера исследователи приводят перемножение двух матриц 4096×4096. Они начали с реализации на Python как одного из самых популярных языков высокого уровня. Например, вот реализация в четыре строки на Python 2:

    for i in xrange(4096):
    for j in xrange(4096):
    for k in xrange(4096):
    C[i][j] += A[i][k] * B[k][j]

    В коде три вложенных цикла, а алгоритм решения основан на школьной программе по алгебре.

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

    Версия Реализация Время выполнения (с) GFLOPS Абсолютное ускорение Относительное ускорение Процент от пиковой производительности
    1 Python 25552,48 0,005 1 0,00
    2 Java 2372,68 0,058 11 10,8 0,01
    3 C 542,67 0,253 47 4,4 0,03
    4 Параллельные циклы 69,80 1,97 366 7,8 0,24
    5 Парадигма «Разделяй и властвуй» 3,80 36,18 6727 18,4 4,33
    6 + векторизация 1,10 124,91 23224 3,5 14,96
    7 + интристики AVX 0,41 337,81 52806 2,7 40,45

    Переход на более эффективный язык программирования уже кардинально повышает скорость выполнения кода. Например, программа на Java будет выполняться в 10,8 раз быстрее, а программа на С — ещё в 4,4 раза быстрее, чем на Java. Таким образом, переход с Python на C означает повышение скорости выполнения программы в 47 раз.

    И это только начало оптимизации. Если писать код с учётом особенностей аппаратного обеспечения, на котором он будет выполняться, то можно повысить скорость ещё в 1300 раз. В данном эксперименте код сначала запустили параллельно на всех 18 ядрах CPU (версия 4), затем использовали иерархию кэшей процессора (версия 5), добавили векторизацию (версия 6) и применили специфические инструкции Advanced Vector Extensions (AVX) в версии 7. Последняя оптимизированная версия кода выполняется уже не 7 часов, а всего 0,41 секунды, то есть более чем в 60 000 раз быстрее оригинального кода на Python.

    Более того, на графической карте AMD FirePro S9150 тот же код выполняется всего за 70 мс, то есть в 5,4 раза быстрее, чем самая оптимизированная версия 7 на процессоре общего назначения, и в 360 000 раз быстрее, чем версия 1.

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

    Например, алгоритм Штрассена для перемножения матриц ещё на 10% ускоряет самую быструю версию кода номер 7. Для других проблем новые алгоритмы обеспечивают ещё большую прибавку в производительности. Например, на следующей диаграмме показан прогресс в эффективности алгоритмов для решения задачи о максимальном потоке, достигнутый в 1975−2015 годы. Каждый новый алгоритм увеличивал скорость вычислений буквально на несколько порядков, а в последующие годы ещё оптимизировался.


    Эффективность алгоритмов для решения задачи о максимальном потоке на графе с n=1012 вершин и m=n11 рёбер

    Таким образом, улучшение алгоритмов тоже вносит свой вклад в то, чтобы «эмулировать» закон Мура программным путём.

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

    «Оборудование, настроенное для конкретных областей, может быть гораздо более эффективным и использовать гораздо меньше транзисторов, позволяя приложениям работать в десятки и сотни раз быстрее, — говорит Тао Шардль, соавтор научной работы. — В более общем плане оптимизация аппаратного обеспечения будет ещё больше стимулировать параллельное программирование, создавая на микросхеме дополнительные области для параллельного использования».

    Тренд на параллелизацию виден уже сейчас. Как показано на диаграмме, в последние годы производительность CPU растёт исключительно благодаря увеличению количества ядер.


    Производительность по тесту SPECint отдельных ядер, а также одно- и многоядерных процессоров с 1985 по 2015 годы. В качестве базовой единицы взят микропроцессор 80386 DX образца 1985 года

    Для операторов дата-центров даже минимальное улучшение производительности ПО может означать большую финансовую выгоду. Неудивительно, что сейчас инициативы по разработке собственных специализированных CPU ведут такие компании как Google и Amazon. Первая выпустила тензорные (нейронные) процессоры Google TPU, а в дата-центрах Amazon работают чипы AWS Graviton.

    За лидерами отрасли со временем могут последовать владельцы других ЦОД, чтобы не проиграть конкурентам в эффективности.

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

    «Рост производительности потребует новых инструментов, языков программирования и аппаратного обеспечения, чтобы обеспечить более эффективное проектирование с прицелом на скорость, — говорит профессор Чарльз Лейзерсон, соавтор научной работы. — Это также означает, что программистам следует лучше понимать, как сочетается софт, алгоритмы и аппаратное обеспечение, а не рассматривать их по отдельности».

    С другой стороны, инженеры экспериментируют с технологиями, которые могут обеспечить дальнейший рост производительности CPU. Это квантовые вычисления, 3D-компоновка, микросхемы со сверхпроводимостью, нейроморфные вычисления, использование графена вместо кремния и др. Но пока эти технологии на стадии экспериментов.

    Если производительность CPU в самом деле перестанет расти, то мы окажемся в совершенно другой реальности. Возможно, нам в действительно придётся пересмотреть наши приоритеты в программировании, а специалисты по ассемблеру станут на вес золота.



    На правах рекламы


    Нужен мощный сервер? Наша компания предлагает эпичные серверы - виртуальные серверы с CPU AMD EPYC, частота ядра CPU до 3.4 GHz. Максимальная конфигурация впечатлит любого — 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe.

    VDSina.ru — хостинг серверов
    Серверы в Москве и Амстердаме

    Comments 462

      +6

      А ещё можно было ба написать версию для тензор ядер… Было бы вообще огонь по скорости.

        +4

        Если так уж нужна скорость, можно сделать специализированный вычислитель (систолический массив?) на каком-нибудь ASIC.

        –3

        Думаю что в будущем, когда остановится развитие ПО backend и desktop приложения будут писать на языках типа c++ и rust. Ведь тогда производительность будет единственным местом где можно будет победить конкурентов

          +50
          Конкурентов зачастую побеждает удобство использования и маркетинг.
            +1
            Точнее, всегда.
            +8
            Если сейчас (да и раньше) программисты писали на медленных яваскрипт и python, то почему через несколько лет, когда производительность еще вырастет, и только потом остановится, все сразу убегут на C++?
              +2
              Потому-что невозможно добавлять фичи бесконечно JS и Python позволяют писать код быстрее в ущерб производительности. В какой-то момент ПО перестанет развиваться активно и станет вопрос производительности.
                +7
                Хм, почему сейчас ПО по-вашему «развивается», а вскоре вдруг перестанет? Нет, ну может быть лет через 50 такое и наступит, но мне к тому моменту будет уже глубоко на это пофиг
                  +4
                  Процессоры стали работать в 2 раза быстрее -> появляется новый фреймворк, который работает в 2 раза медленнее, но ускоряет разработку на 30%. Оптимизировать некогда, нужно осваивать новый фреймворк. А внутри этого фреймворка всё примерно также — некогда было оптимизировать, срочно осваивали новую библиотеку/стандарт/подход. И вот так оно растёт, аки снежный ком — вот такое сейчас «развитие».
                  Когда процессоры будут удваивать скорость лет за 10~15, варианты «работает в 2 раза медленнее, зато разрабатывать на этом в 1.2 раза быстрее» больше не проканают, будет спрос на более быструю реализацию устоявшихся парадигм — и вот тут начнут оптимизировать.
                    0
                    За последние 10 лет производительность одного ядра и выросла примерно в 2 раза. Дальше производительность растёт только если программист осилил многопоточность.
                      0
                      Это на PC и конкретно у Интел.
                      В то время как на мобилках более чем на порядок.
                      А до предела однопоточной производительности ещё далеко.
                        +2
                        В то время как на мобилках более чем на порядок.

                        Так мобилки и стартовали с мегагерц. Ровно так же, как на порядок росли скорости десктопов в нулевых.
                          0
                          Казалось бы, причём тут нулевые, когда речь шла про
                          За последние 10 лет

                          Кривая роста производительности у мобильных чипов сильно другая. Можно объяснить это эффектом «низкой базы», но A4 @ 800MHz десятого года это всё же процессор, который исправно выполнял все «смартфонные» функции.
                          Прогресс быстро шёл из-за того, что на мобильном рынке новая микроархитектура и новый техпроцесс стабильно появляются каждый год, в отличие от :)
                            0
                            Казалось бы, причём тут нулевые

                            Притом что нынешняя кривая роста производительности не сильно отличается от роста десктопов в нулевых.
                            но A4 @ 800MHz десятого года это всё же процессор, который исправно выполнял все «смартфонные» функции.

                            Как и соответствующий P3 ))
                        +1
                        Ну с многопоточностью сейчас гораздо легче, чем 10 лет назад. Даже в древней Дельфе появилось TParallel.For(, вместо ручного создания потоков.
                          +1
                          Как будто проблема параллельных вычислений в самостоятельном создании потоков… Попробуйка распараллелить bsearch или aes-cbc. А если эти потоки ещё и приходится синхронизировать, то вообще начинается ад с дидлоками и рандом-багами.
                            +1

                            Для bsearch если у Вас и 1е8 элементов, то это лишь ~26 операций будет в худшем случае, такое не надо параллелить. Если вы часто ищете — надо параллелить чтение(bsearch) и блокировать запись (вставка нового элемента). Если блокировки частые и мешают работе, можно как-то пул вставок делать и время от вермени сливать массивы.
                            С aes-cbc таже песня, алгоритм использует данные на предыдущем шаге, если у вас данные огромной длинны — то тут я не знаю как можно распараллелить, если у вас много поменьше — то это норм распределить на потоки.

                        +1
                        Потому что парадигма «быстрый старт, потом оптимизация» — работает. Пока оно молодое, важны только возможности, если не совсем тормозное — делать упор на возможности это занять/отжать часть рынка. Выстрелило — есть популярность, начинаем оптимизировать. Тот же php постоянно заявлял «теперь мы быстрее от 10 до 100%» почти в каждой версии, и мельком видел тесты — 7 прилично быстрее чем 5. Ещё плюс — просто обновили версию, оттестировали и «на шару» получили экономию ресурсов.
                        Не выстрелило — не потратили много времени на работу, которая никуда не нужна. Плюс есть даже такой термин «преждевременная оптимизация». «преждевременная оптимизация — корень всех зол» — Дональд Кнут»
                        Другое дело спец вычисления, но их обычно и пишут сразу правильно и на всяких фортранах, лиспах… А если надо ещё быстрее — есть ASIC, например сети — те же циско часто раньше роутинг на асиках делали, получая очень быструю работу.
                          +1
                          есть популярность, начинаем оптимизировать
                          Чего по факту не происходит. Исходят из того, что раз оно популярно то и оптимизировать незачем, лучше потратить деньги на новые фичи из за которых будет лагать ещё больше.
                          Эта цитата выдрана из контекста.
                          Полная цитата
                          Another important aspect of program quality is the efficiency with which the computer's resources are actually being used. I am sorry to say that many people nowadays are condemning program efficiency, telling us that it is in bad taste. The reason for this is that we are now experiencing a reaction from the time when efficiency was the only reputable criterion of goodness, and programmers in the past have tended to be so preoccupied with efficiency that they have produced needlessly complicated code; the result of this unnecessary complexity has been that net efficiency has gone down, due to difficulties of debugging and maintenance.

                          The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.

                          We shouldn't be penny wise and pound foolish, nor should we always think of efficiency in terms of so many percent gained or lost in total running time or space. When we buy a car, many of us are almost oblivious to a difference of $50 or $100 in its price, while we might make a special trip to a particular store in order to buy a 50 cent item for only 25 cents. My point is that there is a time and place for efficiency; I have discussed its proper role in my paper on structured programming, which appears in the current issue of Computing Surveys
                          Не стоит оптимизировать код вообще, если это в конечно счёте даст процент разницы. Но когда речь про изменение производительности в разы, то не оптимизировать крайне глупо!
                            0

                            Конечно нет, зачем это делать, если труд разрабов дороже железа до определенного момента. Как только это иначе и заметили — сразу начинают оптимизировать. Не знаю что у Вас по факту не происходит. Да, было бы приятно, если бы пользователи какой-то ОС прямо сейчас получили прирост скорости в 200%. Но если в случае майрософт это будет стоить пару сотен жизней человеко работы — то нет, спасибо. Все это люди которые чет вперед двигают, и фичи, и безопасность и тд. Если бизнес у которого полно денег будет и на эти задачи забирать людей которые чет умеет, то на остальные задачи ресурсов не хватит, и энтузиазма отказаться от денег. А ведь там есть область к медицине близкая, строительство и тд.
                            И что Вам даст это ускорение, вот один продукт взять — Винда ускорила, все классно, но через время опять фреймворки и пайтоны всякие/js уперлись в потолок по железу, и все. Если все будут оптимизацию в главный угол ставить — то это опять же куча человеко-часов непонятно на что.

                        0
                        По закону Мура каждые 18-24 месяцев количество транзисторов удваивается. До сих пор это происходило за счёт уменьшения их размеров.
                        Сейчас вводится техпроцесс на 5 нм для производства процессоров. В 2022 году будет 2 или 3 нм. В 2024 — 1. В 2026 — .5, в 2028 — .25 — и это предел, это размер атома кремния. Не получится сделать транзистор меньше атома.
                        Ну через многоядерность и параллелизацию что-то получится. Ну ещё площадь кристалла можно увеличить… но всё. В обозримое время мы упрёмся в ограничение производительности железа.
                        Будут ли к тому времени распространены квантовые компьютеры и как они будут программироваться — вопрос.
                          0
                          Давно уже упёрлись и сейчас все эти нанометры — банальный маркетинг.

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

                          Проектные нормы в микроэлектронике: где на самом деле 7 нанометров в технологии 7 нм?
                        0
                        Понятно, что статически типизированные языки имеют фундаментальный бонус в скорости.
                        Но тот же python с развитием jit-компиляции (pypy, numbaJIT) и добавлением опциональной типизации — возможно, ещё долгое время можно будет выжимать из ускорения интерпритатора и JIT-компиляции. ( даже если не появится террагерцевых процессоров, квантовых компьютеров оптических вычислений и классический закон Мура встанет )
                          –1
                          Понятно, что статически типизированные языки имеют фундаментальный бонус в скорости.


                          Неочевидно, обоснуйте свой тезис.
                            +2
                            Возможно, стоило сформулировать точнее: не в любом случае статически типизированный код — быстрее, но есть случаи, когда это априори — так, а в остальных — не медленнее. ( из чего следует, что в совокупности — быстрее)

                            Как я себе вижу: компилятор может оптимизировать некоторые вещи, зная тип данных (
                            т.е. если функции на вход всегда приходит массив int'ов — оптимизировать проще, чем если это может быть int, float, строка, или вообще разные кастомные классы, для которых определено сложение друг с другом и деление на int. ( понятно, что такое можно написать и для статически типизированного языка, но если мы ищем среднее арифметическое массива интов [например, средняя зарплата], то у компилятора/интерпретатоора вообще не будет шансов из логики понять, что, например, строк там не будет. ( и и я не знаю динамически типизированных языков, где программист сможет это явно указать [python type hints — не влияют на оптимизацию, numba — статически типизирована, pypy — будет оптимизировать только при многократном вызове с интами])
                            )
                              0
                              Динамическая типизация всего лишь означает, что тип аргумента функции становится известен во время выполнения (например, прямо перед её запуском), а не заранее при обработке программы целиком. Соответственно, в этот момент можно компилировать функцию под конкретные типы. В случае, если типы аргументов действительно не меняются, оверхед по сравнению с компиляцией «заранее» будет нулевой.
                              Из языков ровно так работает, например, julia — причём явным образом типы указывать не требуется (но можно).
                              Numba в питоне тоже, конечно, никак не статически типизирована — до выполнения программы типы аргументов могут быть неизвестны.
                                +1
                                def div(a,b):
                                    return a/b
                                

                                В каком месте интерпретатор питона поймет что я передал ему строки, я так понимаю прям перед делением он выполнит эту проверку. В то время как статически типизированный язык просто интерпретирует куски памяти как int float или как мы их объявляли, ничего не будет проверять и поделит. Разве это не выигрышь времени выполения?
                                  0
                                  Нигде не поймёт — ну так я и не писал, что питон так делает (но см. в конце комментария про нумбу).
                                  Julia, например, компилирует в такое:
                                  > f(a, b) = a / b
                                  > @code_native f(1.0, 2.0)  # float
                                  # выдаёт ассемблерный код:
                                  # vdivsd	%xmm1, %xmm0, %xmm0
                                  # retq
                                  > @code_native f(1, 2)  # int
                                  # vcvtsi2sd	%rdi, %xmm0, %xmm0
                                  # vcvtsi2sd	%rsi, %xmm1, %xmm1
                                  # vdivsd	%xmm1, %xmm0, %xmm0
                                  # retq
                                  > @code_native f(big"1.0", 2.0)  # bigfloat - вызов соответствующего метода
                                  # pushq	%rax
                                  # movabsq	$"/", %rax
                                  # callq	*%rax
                                  # popq	%rcx
                                  # retq
                                  > f("abc", 1)  # строки делить нельзя
                                  # MethodError: no method matching /(::String, ::Int64)
                                  

                                  Эту функцию, конечно, можно использовать и внутри других функций
                                  Заголовок спойлера
                                  function g(x, b)
                                      res = 0.0
                                      for a in x
                                          res += f(a, b)
                                      end
                                      return res
                                  end
                                  > a = rand(100)
                                  > @code_native g(a, 2.0)
                                  #     movq    8(%rdi), %rax
                                  #     testq   %rax, %rax
                                  #     jle L74
                                  #     movq    (%rdi), %rcx
                                  #     vmovsd  (%rcx), %xmm1           # xmm1 = mem[0],zero
                                  #     vdivsd  %xmm0, %xmm1, %xmm1
                                  #     vxorpd  %xmm2, %xmm2, %xmm2
                                  #     vaddsd  %xmm2, %xmm1, %xmm1
                                  #     cmpq    $1, %rax
                                  #     je  L69
                                  #     movl    $1, %edx
                                  #     nopw    (%rax,%rax)
                                  # L48:
                                  #     vmovsd  (%rcx,%rdx,8), %xmm2    # xmm2 = mem[0],zero
                                  #     vdivsd  %xmm0, %xmm2, %xmm2
                                  #     vaddsd  %xmm2, %xmm1, %xmm1
                                  #     incq    %rdx
                                  #     cmpq    %rax, %rdx
                                  #     jb  L48
                                  # L69:
                                  #     vmovapd %xmm1, %xmm0
                                  #     retq
                                  # L74:
                                  #     vxorps  %xmm1, %xmm1, %xmm1
                                  #     vmovaps %xmm1, %xmm0
                                  #     retq
                                  


                                  Как видно, единственный оверхед здесь после запуска — один раз скомпилировать функцию для каждого требуемого типа аргументов. Затем выполнение идёт без замедлений относительно нативного кода.
                                  При этом типизация динамическая, и можно составить такую функцию:
                                  h(a) = f(rand(Bool) ? big"1.0" : 1.0, a)
                                  

                                  Здесь в машинном коде появляется проверка типа при запуске f, и в зависимости от него запускается либо одна либо другая (скомпилированная, часто даже заинлайненная) её версия.

                                  В питоне нумба, как я писал, тоже по сути динамически типизированная — ведь статических типов в нём в принципе нет.
                                  @numba.njit
                                  def g(x, b):
                                      res = 0.
                                      for a in x:
                                          res += a / b
                                      return res
                                  a1 = np.random.rand(100)
                                  a2 = np.random.rand(100).astype(int)
                                  g(a1 if np.random.rand() > 0.5 else a2, 2.0)
                                  

                                  Тип аргумента не известен до выполнения, что никак не мешает компилировать функцию в соответствующий момент. Просто в питоне это работает для весьма ограниченного набора возможностей языка (то, что поддерживается нумбой), а джулия компилирует любой код в машинный перед выполнением, в том числе между библиотеками и пользовательскими типами.
                                    0
                                    Как видно, единственный оверхед здесь после запуска — один раз скомпилировать функцию для каждого требуемого типа аргументов.

                                    А какой требуемый тип? По вашим примерам ничего не видно, т.к. не показан код, который вызывает эти функции и выясняет, есть ли уже откомпилированная и нужно ли jit-компилировать ещё одну. Оверхед, по сравнению со статической компиляцией именно там.

                                    Затем выполнение идёт без замедлений относительно нативного кода.

                                    Доказательства?
                                    @code_native f(1, 2) # int
                                    vcvtsi2sd %rdi, %xmm0, %xmm0
                                    # vcvtsi2sd %rsi, %xmm1, %xmm1
                                    # vdivsd %xmm1, %xmm0, %xmm0
                                    # retq

                                    Ага, «инт». (╯°□°)╯︵ ┻━┻
                                      0
                                      По вашим примерам ничего не видно, т.к. не показан код, который вызывает эти функции

                                      Весь код показан — просто открываете REPL джулии и вводите ровно то, что в моём комментарии, те строки которые не с # начинаются. То, что с # в начале — это будет вывод. Можно и в скрипт запихать конечно, только явным образом print'ы проставить.
                                      Больше кода никакого и нет, если конечно вы не имеете в виду реализацию самого компилятора или что-то подобное.
                                      не показан код, который вызывает эти функции

                                      Итак, вызывающий код — это просто f(1, 2), g(a, 2.0) и т.п.

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

                                      А какой требуемый тип?

                                      Может я не очень вас понял, но требуемый тип — это просто тип, с которым нужно скомпилировать функцию. Есть вызов f(1, 1) — компилируем f(::Int, ::Int); есть f(1.0, 1.0) — это f(::Float, ::Float), и т.д. Если с такими типами уже компилировали — ничего не делаем, просто вызываем (или инлайним) имеющуюся.

                                      Ага, «инт»

                                      Да, возможно я не уточнил, т.к. считал очевидным — какой тип имеют литералы. 1 и 2 — типа Int64, поэтому f(1, 2) вызывает f(::Int, ::Int). 1.0, 2.0 — это Float64.

                                      Затем выполнение идёт без замедлений относительно нативного кода.

                                      Доказательства?

                                      Если брать приведённый мой пример функции f и её вызова в g — то там же приведён ассемблерный код, который будет выполняться при дальнейших вызовах с теми типами. При выполнении этого кода уже не важно, когда он появился — заранее или во время выполнения — скорость будет такая же. С чего вообще по-другому может быть?

                                      Например, предложенный в моём предыдущем комментарии вызов g(a, 2.0) у меня на лаптопе выполняется за ~70 ns. Сравнивать с C/C++ лениво, но для последовательных делений и сложений по 100 раз время вполне соответствует ожидаемому от нативного кода.
                                        0
                                        При выполнении этого кода уже не важно, когда он появился — заранее или во время выполнения — скорость будет такая же. С чего вообще по-другому может быть?
                                        Даже ели допустить, что Julia в runtime'е выполняет настолько качественную оптимизацию насколько возможно (что вряд ли, так как это занимает время) — инлайнинг, к примеру, в такой модели совершенно неприменим. Да и само переключение компиляция/выполнение бесплатно не проходит.
                                          0
                                          инлайнинг, к примеру, в такой модели совершенно неприменим

                                          Не знаю, откуда такое мнение. Ведь прямо в комментарии выше, где я привожу пример выдаваемого ассемблерного кода, показан инлайнинг! А именно, функция f вставлена в g — никакого дополнительного вызова не происходит.

                                          Даже ели допустить, что Julia в runtime'е выполняет настолько качественную оптимизацию насколько возможно (что вряд ли, так как это занимает время)

                                          Да и само переключение компиляция/выполнение бесплатно не проходит.

                                          Не вижу никакой проблемы проводить качественную оптимизацию во время выполнения программы, перед первым запуском каждой функции с новыми типами аргументов. Как я и писал, эта компиляция — единственный оверхед во время работы, но он случается только один раз на каждую комбинацию <функция, типы аргументов>.
                                            0
                                            Не знаю, откуда такое мнение.
                                            Ну допустим Вы наткнулись на вызов функции и захотели его заинлайнить — как Вы это сделаете, если код функции, в которую нужно инлайнить, уже готов (это ведь он выполняется сейчас)? Единственный способ — вставить код с помощью memcpy, но уж лучше тогда не-inline вызов использовать.
                                            Ага, нашел Ваш пример. ОК, есть инлайнинг, но видимо тогда все дерево вызовов скомпилировано за раз, а не по одной функции, как Вы говорите. Ассемблер, кстати, странновато выглядит.
                                            Не вижу никакой проблемы проводить качественную оптимизацию во время выполнения программы
                                            Дело в том, что качественная оптимизация использует данные обо всей программе, а не об одной конкретной функции. Например, если бы в Вашем примере было целочисленное деление — хороший оптимизатор бы заметил, что второй параметр всегда константный, и заменил бы его на умножение на константу. А компиляция по одной функции такого не сделает, откуда ей об этом знать?
                                            Как я и писал, эта компиляция — единственный оверхед во время работы
                                            Ага, а как на счет кэша скомпилированных функций? Перед каждым вызовом будьте добры сделать лукап, ну и апдейт кэша после компиляции, если вхождение не было найдено.
                                              0
                                              Ну допустим Вы наткнулись на вызов функции и захотели его заинлайнить — как Вы это сделаете, если код функции, в которую нужно инлайнить, уже готов

                                              Как именно это технически реализовано — не разбирался и не знаю, могу только предполагать. Видимо, когда вызывается функция с конкретными типами аргументов, проводится некий анализ и вызываемых из неё функций — если они «простые», то инлайнятся.

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

                                              второй параметр всегда константный, и заменил бы его на умножение на константу

                                              Опять же, детали реализации я не знаю, но constant propagation в джулии давно завезли. Весьма вероятно, что он менее полный по сравнению с условным Си, просто из-за возраста языка. Но фундаментальных ограничений нет, во многих случаях он уже работает.

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

                                              Не понял, зачем лукап перед каждым вызовом? Когда типы выводятся компилятором, этого точно не происходит; если типы невозможно вывести — ставится «лукап», либо из нескольких вариантов, либо если вообще ничего неизвестно — полноценный динамический.
                                              Например, когда есть два варианта:
                                              > f(a, b) = a * b
                                              > h(a) = f(rand(Bool) ? 1 : 1.0, a)
                                              > h(1)  # возвращает либо 1::Int, либо 1.0::Float
                                              > @benchmark h(1)  # показывает, что h(1) занимает 5-8 ns
                                              > @code_native debuginfo=:none h(1)
                                              # под спойлером
                                              

                                              Заголовок спойлера
                                              Видно и целочисленное imulq, и дробное vmulsd. Более детально я в ассемблере не шарю :)

                                              pushq %r14
                                              pushq %rbx
                                              pushq %rax
                                              movq %rsi, %rbx
                                              movq %rdi, %r14
                                              movabsq $rand, %rax
                                              callq *%rax
                                              movabsq $4607182418800017408, %rdx # imm = 0x3FF0000000000000
                                              movl $1, %ecx
                                              testb $1, %al
                                              cmoveq %rdx, %rcx
                                              jne L70
                                              vcvtsi2sd %rbx, %xmm0, %xmm0
                                              vmovq %rcx, %xmm1
                                              vmulsd %xmm1, %xmm0, %xmm0
                                              vmovsd %xmm0, (%r14)
                                              movb $1, %dl
                                              xorl %eax, %eax
                                              jmp L81
                                              L70:
                                              imulq %rbx, %rcx
                                              movq %rcx, (%r14)
                                              movb $2, %dl
                                              xorl %eax, %eax
                                              L81:
                                              addq $8, %rsp
                                              popq %rbx
                                              popq %r14



                                              Более полезный пример:
                                              # если дали nothing - вернуть ноль, иначе умножить на 2
                                              > f(x) = 2*x
                                              > f(::Nothing) = 0
                                              
                                              # хотим суммировать f(x[1]) + f(x[2]) + ...
                                              > g(x) = sum(f, x)
                                              
                                              # массив int'ов:
                                              > a = rand(Int, 1000)
                                              > @benchmark g(a)
                                              # 80-90 ns
                                              
                                              # массив int'ов и nothing'ов вперемешку:
                                              > a = [rand(Bool) ? rand(Int) : nothing for _ in 1:1000]
                                              > @benchmark g(a)
                                              # 200-220 ns
                                              

                                              В общем, даже в этой ситуации, где типы принципиально нельзя вывести статически (и есть лукап во время выполнения), получился весьма эффективный код. Даже simd используется, судя по времени.
                                                0
                                                Ладно, кажется я понял в чем проблема — в терминологии. Правильно ли я понял, Вы под вызовом функции подразумеваете команду вроде "> @benchmark g(a)"? Ну вот я это воспринимаю как запуск программы. А вот внутри себя она уже вызывает функции — это инструкции call или заинлайненный код других функций. Так вот я утверждаю, что каждая такая программа перед запуском полностью компилируется (включая все то, что она вызывает). Согласны с таким образом сформулированной позицией?
                                                Этот подход эффективен — если Вам нужно запустить одну такую команду-программу. Но, опять же, есть аналогичная проблема — компилятор вынужден анализировать команды по одной, не видя общей картины. Например:
                                                > f(x) = x
                                                > g(x) = sum(f, x)
                                                > a = [1 for _ in 1:1000]
                                                > @benchmark g(a)
                                                Если этот код компилируется по одной команде — будет цикл с суммированием. А если весь сразу — будет просто «return 1000».
                                                  0
                                                  Так вот я утверждаю, что каждая такая программа перед запуском полностью компилируется (включая все то, что она вызывает). Согласны с таким образом сформулированной позицией?

                                                  По-моему это принципиально невозможно сделать. Например:
                                                  > g() = eval(Meta.parse(readline()))
                                                  # вызываем g(), набираем в консоли код - он исполняется
                                                  
                                                  # или
                                                  
                                                  > g(x) = some_function(deserialize(x))
                                                  # вызываем g("file_name"), из этого файла десериализуется объект, на нём вызывается some_function
                                                  
                                                  # или даже так
                                                  
                                                  > g() = eval(Meta.parse(randstring(Char.(30:128), 123)))
                                                  # вызывать g()
                                                  # обычно будет ошибка,
                                                  # но возможно иногда случайно получится валидный код
                                                  

                                                  Во всех трёх случаях при вызове функции g() нельзя определить, какие ещё функции будут вызваны. Это можно сделать только потом, когда часть кода g() будет выполнена.
                                                    0
                                                    Если этот код компилируется по одной команде — будет цикл с суммированием. А если весь сразу — будет просто «return 1000».

                                                    А для какого языка компилятор сможет сделать "return 1000", если a имеет ссылочный тип?


                                                    Если a будет иммутабельного типа и помечена как константа, то всё свернётся (но это не точно). Например, с пакетом StaticArray, добавляющим иммутабельные массивы фиксированного размера:


                                                    julia> f(x) = x
                                                    julia> g(x) = sum(f, x)
                                                    julia> const a = @SVector [1 for _ in 1:1000]
                                                    julia> @code_native (function () g(a) end)()
                                                        .text
                                                    ; ┌ @ REPL[8]:1 within `#10'
                                                        movl    $1000, %eax             # imm = 0x3E8
                                                        retq
                                                        nopw    %cs:(%rax,%rax)
                                                    ; └

                                                    (если смотреть код для g(a), то покажет код для g только в предположении, что аргумент — статический массив, не подставляя конкретное содержимое, поэтому в последней команде вызов обёрнут в функцию).

                                            0
                                            Весь код показан — просто открываете REPL и вводите ровно то, что в моём комментарии
                                            Ещё раз. У вас не показан код который вызывает оверхед. И так понятно, что leaf-функции будут откомпилированы в нативный код. Смотреть на них не интересно.

                                            Оверхед будет в программе, которая вызывает вашу функцию, если функция не проинлайнена.

                                            При выполнении этого кода уже не важно, когда он появился — заранее или во время выполнения — скорость будет такая же. С чего вообще по-другому может быть?

                                            Т.е. рантайм затраты на лукап и компиляцию функции вы не считаете оверхедом?
                                            *facepalm*

                                            Вызвать функцию в 5 строк из REPL и выполнять некий софт со 100 мегабайт кода это несколько разные вещи.

                                            Да, возможно я не уточнил, т.к. считал очевидным — какой тип имеют литералы. 1 и 2 — типа Int64, поэтому f(1, 2) вызывает f(::Int, ::Int).


                                            Языки такого плана обычно не умеют нормально работать с int.
                                            Ваша функция с int не выполняет целочисленное деление.
                                            Она переводит int в double, а потом делит даблы.

                                            Например, предложенный в моём предыдущем комментарии вызов g(a, 2.0) у меня на лаптопе выполняется за ~70 ns.


                                            Так же из repl дёрнули? Так он компильнулся / проинлайнился, оверхед вызова скрыт. Это не показывает ничего, кроме наличия jit — компилятора.
                                            К тому же про 70нс я очень сильно сомневаюсь.
                                            70 нс это латентность одного обращения к памяти.

                                            Давайте посмотрим на инструкцию VDIVSD (на 4GHz Skylake)
                                            :VDIVSD xmm, xmm, xmm L: 3.49ns= 14.0c T: 1.00ns= 4.00c
                                            В цикле 100 итераций, но div не в цепочке зависимости, поэтому имеем время их исполнения не 14*100, а 4*100 тактов == 100 нс, если компилятор не векторизировал цикл (буду приятно удивлён, если векторизировал).
                                              0
                                              Ваша функция с int не выполняет целочисленное деление.
                                              Она переводит int в double, а потом делит даблы.
                                              Вроде бы у Julia такая семантика деления, целочисленное там другим значком.
                                              docs.julialang.org/en/v1/manual/mathematical-operations
                                                0
                                                Оверхед будет в программе, которая вызывает вашу функцию, если функция не проинлайнена.

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

                                                Т.е. рантайм затраты на лукап и компиляцию функции вы не считаете оверхедом?

                                                Не знаю, где вы это прочитали. Про оверхед на компиляцию я явным образом писал, что он есть. «Лукап» функции после компиляции будет только если тип не вывелся — см. предыдущий абзац.

                                                Языки такого плана обычно не умеют нормально работать с int.

                                                Какого «такого» плана? Как «нормально»? Делить нацело можно, делить по-обычному тоже можно — просто это разные операторы.
                                                Ваша функция с int не выполняет целочисленное деление.
                                                Она переводит int в double, а потом делит даблы.

                                                Конечно, если я в функции пишу "/" то я и ожидаю деление — без округления нацело, если вдруг в эту функцию передали инты. Нужно округлённое деление — так и пишите в коде, будет вам (стандартное хардверное) деление нацело.

                                                Так же из repl дёрнули? Так он компильнулся / проинлайнился, оверхед вызова скрыт. Это не показывает ничего, кроме наличия jit — компилятора.

                                                Поведение в repl и в коде из файлов в аспекте скорости и подхода к компиляции абсолютно никак не отличается.

                                                К тому же про 70нс я очень сильно сомневаюсь.
                                                70 нс это латентность одного обращения к памяти.

                                                При бенчмаркинге функция запускается много раз, так что всё в кэше находится. Разумеется, никак нельзя достичь 70 нс если отсчитывать время от запуска программы до вывода результата на экран.

                                                В цикле 100 итераций, но div не в цепочке зависимости, поэтому имеем время их исполнения не 14*100, а 4*100 тактов == 100 нс,

                                                Вполне возможно, что я действительно куда-то не туда посмотрел в прошлый раз. Сейчас перепроверил — выходит 100-110 ns.

                                                если компилятор не векторизировал цикл (буду приятно удивлён, если векторизировал).

                                                Вроде бы, судя по командам, цикл не векторизирован. Для векторизации нужно перед словом for добавить simd — тогда время работы сокращается раза в 2 у меня.
                              0
                              На питоне это всё тоже можно было-бы написать довольно быстро (хотя-бы попробовать), с помощью пакетов Numpy + Numba
                                +4

                                Numpy — это не питон

                                  +2
                                  Это скользкая дорожка
                                  В таком случае можно говорить что и print это не питон
                                    0

                                    Вопрос в том, идёт ли ваш вычислительный алгоритм через интерпретатор или нет. print — это IO, его без обращения к ОС вообще трудно написать, а там С.

                                    0
                                    Так весь Питон — не Питон. В стандартной реализации — это Си.
                                    +2
                                    Чтобы писать на Python «правильно», надо на нём писать общую логику, а всё, что хоть как-то требовательно к производительности, засовывать в модули. Которые на Си, который уже совсем не Python. И да, NumPy именно так и сделан.
                                  +2
                                  Думаю что в будущем, когда остановится развитие ПО backend и desktop приложения будут писать на языках типа c++ и rust.

                                  Не уверен. Оптимизации из статьи начиная с четвертой не очень то и зависят от языка программирования. Сборщик мусора тут тоже мимо — на весь тест три объекта.
                                  Я бы поставил на языки с нормальный типизацией, которые будут давать возможность нормально задавать на уровне типов подобные оптимизации. Ну или для начала удобные библиотеки для работы со стандартными оптимизациями.
                                    +7
                                    Я бы поставил на языки с нормальный типизацией, которые будут давать возможность нормально задавать на уровне типов подобные оптимизации.

                                    А чего, выразил какое-то преобразование на уровне типов, на уровне термов доказал его корректность, компилятор это видит и может сворачивать условный map f . map g в map (f . g).


                                    Будущее за языками с зависимыми типами даже с точки зрения производительности, ура!

                                    +13

                                    И по прежнему 80% будет уходить на ожидание, диска ли, сети ли… Но можно ждать быстрее!

                                      +1
                                      Вспомнил байку, как молодой программист в Microsoft оптимизировал цикл, в котором его компьютер находился 80% времени. Правда этот цикл оказался циклом бездействия процессора.
                                        +1
                                        Собственно, оптимизация энергопотребления в этом цикле и позволила процессорам прийти в мобильный сегмент.
                                        0
                                        Диски понемногу ускоряются, канал тоже в целом становится шире, так что самым узким горлышком для веба останется неторопливый сетевой протокол. И видимо, это следующее место в очереди на оптимизацию)
                                          +3

                                          Не уверен. Все приложения всё ещё используют БД и там как упирались в диск, та и упираемся. С latency пока не сильно хорошо.

                                            0
                                            PCI-E хранилище в помощь. Может даже рейды
                                              0
                                              на серверах. а у пользователей? код вэбом не ограничивается.
                                                0
                                                m.2 хранилища относительно дешёвые тоже есть, и при этом шустрые
                                                  0

                                                  Попытка использовать samsung 970 под бд привела к его смерти за 2 месяца. Сначала тоже казалось, что отличное решение и под ноут подходит. Сейчас у меня хорошего решения нет. Да и по цене я не назвал бы это массовым.

                                                    0
                                                    2 месяца это что-то странное, похоже на брак.
                                                    У меня 2 штуки SSD Samsung работают почти непрерывно 6 лет — один система, другой рабочие файлы. Так вот смарт показывает оставшийся ресурс 91 и 99% соответственно.
                                                      0

                                                      Я был немилосерден. У меня циклы разработки такие, что записываются по 300-700gb и стирается и по-новой раз в пару-тройку дней.

                                                        +1
                                                        Ну грубо можно принять 200 ГБ/день. За два месяца без выходных получится 12 ТБ — это на порядок меньше даже заявленного ресурса. А реальный, согласно тестам, должен быть больше ещё примерно на порядок. То есть ваш диск отработал ~1% того, что должен был.
                                                      0

                                                      Странно, потому-что у меня с хардами прямо противоположная ситуация. Если использовать под систему и на нём-же проводить всякие сборочки: начинал дохнуть где-то через полгода-год. С ssd ситуация противоположная: 2 года, 500 гб обьём (CT500P1SSD8), используется в качестве системного диска и под проекты тоже (брался из-за хорошего показателя 4k random write). 24.6 терабайт записаных за этот период, полёт нормальный (drive remaining life рапортует 90%), нареканий ноль.

                                                        0
                                                        Странно, потому-что у меня с хардами прямо противоположная ситуация. Если использовать под систему и на нём-же проводить всякие сборочки: начинал дохнуть где-то через полгода-год. С ssd ситуация противоположная: 2 года, 500 гб обьём (CT500P1SSD8), используется в качестве системного диска и под проекты тоже (брался из-за хорошего показателя 4k random write). 24.6 терабайт записаных за этот период, полёт нормальный (drive remaining life рапортует 90%), нареканий ноль.


                                                        Ну а у меня за последние 10 лет сдохло 20% SSD и 5% HDD.
                                                          0

                                                          Что за ssd-хи хоть?

                                                            0
                                                            Что за ssd-хи хоть?

                                                            Они померли и кто их уже помнит.
                                                            Хорошие модели. Не дешёвые. Я хреновых не покупаю.
                                                0
                                                Там где важна скорость — все базы данных давно крутятся на SSD, in_memory для кеширования тоже в помощь. Понятно, что это дороже — но варианты есть. У меня сейчас на проекте в стате по нгинксу — 99-ый квантиль укладывается в 40ms на апи(а на части эндпойнтов и в 20ms) — при том что там идёт работа с тремя разными базами данных, две in_memory, одна обычная. А главная страница — ~2.4 секунды до полной загрузки(меньше секунды до отображения интерфейса), 2mb данных, под сотню http запросов — стили, скрипты, картинки, и основное время в таймингах — ttfb.

                                                Понятно, что если брать локальное приложение, оно будет упираться в диск как в самый медленный элемент, но в вебе всё же по тормозам лидирует сеть.
                                                  0

                                                  С серверной частью легче, вопрос денег. По части дисков.
                                                  И да, сеть. Весь вопрос о том, что мы, конечно, можем ускорять код наших приложений, но latency часто убивает все приросты производительности.

                                                  0
                                                  Все приложения всё ещё используют БД и там как упирались в диск, та и упираемся

                                                  Что, прямо все-все приложения на свете? :)
                                                  В кровавом энтепрайзе работают не только лишь все.(с)
                                                  У меня вот ни одна задача не упирается в диск.
                                                  Когда проект в десятки мегабайт кода собирается на 16 ядрах, SSD загружен на 0-1%.
                                                  0
                                                  А вообщем то решают эту задачу.
                                                  Просто обычно в варианте «у нас спутниковый канал а значит пинг в полсекунды и полоса узкая а нам надо работать».
                                                  Как в тупом варианте для обычных пользователей (которым http нужен(тогда еще https был редкий) — Globax/TelliNet (спецпрокся сразу запрашивает кроме страницы еще и картинки) так и серьезные оптимизации протоколов вроде SMB чтобы снизить количество запросов + кэшировать информацию локально и передавать дельты. Это например продукты от Riverbed делают.

                                                  В HTTP/2 есть попытки оптимизировать по минимуму (например — то что не надо каждый раз соединение устанавливать и гонять TCP и TLS рукопожатия)

                                                    0
                                                    В HTTP/2 есть попытки оптимизировать по минимуму (например — то что не надо каждый раз соединение устанавливать и гонять TCP и TLS рукопожатия)

                                                    Как ни странно, этого не приходится делать даже в HTTP/1.1, если использовать заголовок «Connection: keep-alive». Причём, это используется везде, даже в библиотеках вроде requests для Python и cURL для PHP.
                                                      0
                                                      Вторая версия мультиплексирует все соединения к серверу в одно. Да и keep-alive регулярно обрывают для избежания всяких там проблем, что браузеры, что вебсервера.
                                                      0
                                                      Как в тупом варианте для обычных пользователей (которым http нужен(тогда еще https был редкий) — Globax/TelliNet (спецпрокся сразу запрашивает кроме страницы еще и картинки)


                                                      Я правильно понимаю, что это те системы, которые передают все данные всех пользователей через 1 спутниковый канал на землю, а исходящий траффик через другой канал?
                                                      И именно там была популярна «рыбалка», когда более подкованный пользователь перехватывал входящие спутниковые пакеты, адресованные не ему, и мог прочитать чужой http-траффик. (привет угон кукисов и прочие радости)
                                                    0
                                                    Расскажите это играм/криптовалютам/видеообработке.
                                                      0

                                                      Ох… Прямо в сердце… Трудно сделать базу шустрой на стороне клиента. А надо.

                                                    +1
                                                    Полно задач, где на производительность вообще наплевать. Отчёт посчитается сегодня — отлично, послезавтра — тоже сойдёт.
                                                      +1

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

                                                    +23
                                                    Робин Мартин предполагает, что хороший способ приступить к решению проблемы — разделить библиотеки. Вместо того, чтобы создавать одну большую библиотеку, которая делает всё возможное, просто создать много библиотек.

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

                                                    Это как? Если вместо одной большой библиотеки будет много маленьких, каким образом я уменьшу количество зависимостей?


                                                    Разве это не тот путь, которым пошли с npm.js, и который в итоге приводит к 13000 зависимостей?

                                                      +5
                                                      Это как? Если вместо одной большой библиотеки будет много маленьких, каким образом я уменьшу количество зависимостей?

                                                      Большая библиотека А может иметь компоненты b, c, d с зависимостями E,F,G соответственно. То есть библиотека A зависит от библиотек E, F, G. Разделяя библиотеку на библиотеки Ab, Ac, Ad (с зависимостями E,F,G соответственно), мы даём возможность пользователю подключить только библиотеку Ab c зависимостью E (если ему не нужны компоненты c, d), и не тянуть зависимости F, G ненужных компонентов.


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

                                                        +8
                                                        Это именно то, к чему пришел npm. В котором «меньшими порциями» подключить себе 13000 зависимостей — сейчас довольно просто.
                                                          +1

                                                          Это связано со сложностью ПО. Если есть 13000 различных функций (или связанных групп функций), число библиотек будет такого же порядка.

                                                            +28
                                                            число библиотек будет такого же порядка

                                                            Как по мне, это проблема. В общем случае, я бы предпочел одну большую библиотеку + tree shaking, чем 10 маленьких:


                                                            • больше вероятность, что она написана в одном стиле;
                                                            • не возникнет конфликтов между версиями, когда библиотека A требует библиотеку C v1, а библиотека B требует библиотеку C v2;
                                                            • меньше вероятность дублирования кода, поскольку компоненты одной библиотеки знают о существовании друг друга;
                                                            • проще обновить одну библиотеку на новую версию, чем 10;
                                                            • компоненты одной библиотеки будут совместимы между собой;
                                                            • и т.д.
                                                              0

                                                              Согласен, но, на мой взгляд, проблема библиотек не только и не столько в том, что в них содержится "лишний" код (кстати, tree shaking всё-равно не сможет удалить абсолютно весь лишний код), сколько в том, что несколько последних поколений разработчиков обучены иначе думать — они ищут и подключают библиотеки на каждый чих, даже там, где можно было решить проблему написав десяток строк кода ручками.

                                                                0
                                                                С другой стороны, этот десяток строк кода надо протестировать в хвост и в гриву, а в библиотеке(в идеале, конечно) всё уже протестировано. Сам люблю велосипеды писать, когда требуемый функкционал укладывается в 10-20 строк, но иногда потом отлавливаю дурацкие ошибки.
                                                                  +2

                                                                  Это распространённое заблуждение:


                                                                  • Этот десяток строк нужно протестировать ровно так же, как и любой другой десяток строк нашего кода — никакой особой разницы тут нет.
                                                                  • Насколько протестирован аналог этих строк в библиотеке — обычно никто не знает, и при выборе библиотеки на это не смотрит.
                                                                  • Поиск подходящих библиотек и выбор из нескольких альтернатив занимает время, нередко превышающее время на написание и тестирование этих 10 строк.
                                                                  • Добавление дополнительной зависимости в проект создаёт дополнительные риски и увеличивает стоимость поддержки проекта само по себе (которые принято игнорировать, но если прятаться под одеялом то монстр всё-равно никуда не исчезнет) — лицензии, зависимость от стороннего вендора, куча лишнего кода с потенциальными уязвимостями и т.д. (подробнее в https://habr.com/ru/post/443620/). Но если их не игнорировать, то стоимость поддержки и тестирования своих 10 строк почти всегда окажется значительно ниже стоимости поддержки дополнительной зависимости.

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

                                                                    0
                                                                    Я с вами в этом и не спорю, на мой взгляд всегда нужно находить золотую середину. Глупо подтягивать библиотеку для проверки числа на чётность, но ещё более дурацкая идея — писать свой ORM, например. И да, у меня в проекте самописный фрэймворк с самописным ORM, в котором я периодически отлавливаю новые ошибки и переписываю часть функционала) Для увеличения опыта — полезно, но будь у меня воля выбирать — я бы лучше подтянул готовую библиотеку)
                                                                      0
                                                                      Вы мой товарищ по несчастью, сейчас тоже мучаюсь на проекте с кучей велосипедов, в том числе с самописным ORM, к сожалению выпилить этот кошмар из проекта не представляется возможным, по трудозатратам это будет сложнее чем просто переписать все заново.
                                                          0

                                                          Не, то что вы описали, это про "в используемых библиотеках тоже будет меньше своих зависимостей" – тут я не спорю. Транзитивных зависимостей может быть меньше. Прямых зависимостей никак не может стать меньше.

                                                            +1

                                                            Прямые зависимости — они явные. Транзитивные зависимости — неявны, этим они и страшны.

                                                              0

                                                              И? Какое отношение это имеет к моему изначальному вопросу?

                                                                0

                                                                Транзитивные зависимости вызывают большее беспокойство, чем прямые (прямые подключаются явно, а не ВНЕЗАПНО, они все видны). Описанный способ борется с лишними транзитивными зависимостями.

                                                                  +1

                                                                  Описанный способ приведет (и приводит) к аду с управлением зависимостями, когда библиотека A зависит от библиотеки C v1, а библиотека B зависит от библиотеки C v2. А я про эту библиотеку C вообще ничего не знаю, и она мне нафиг не сдалась бы. И чем больше таких микро-библиотек, тем больше вероятность конфликтов.


                                                                  Но это все лирика, повторюсь, к моему изначальному вопросу это не имеет никакого отношения.

                                                                    0
                                                                    к моему изначальному вопросу это не имеет никакого отношения.

                                                                    По-моему, я описал механизм, как эта идея работает. Это отвечает на вопрос "как?"

                                                                      0

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


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


                                                                      А вы мне в этой ветке говорите про то, что транзитивные зависимости вызывают большее беспокойство. Отсюда и вопрос: "И что?"

                                                                        –1
                                                                        Я утверждаю, что это невозможно даже в теории. А на практике даже общее количество прямых и транзитивных зависимостей увеличивается, а не уменьшается.

                                                                        Это не так.

                                                                      +1
                                                                      Мне кажется, идеальными были бы библиотеки, которые вообще не тянут зависимостей. Пусть там будет на пять строк больше, но когда библиотека для проверки чётности числа тянет за собой библиотеку которая проверяет нечётность числа — это адок.
                                                                        +1
                                                                        Ваш пример немного не к месту. То, что вы описали, это то, что мы имеем уже сейчас и без разбиения библиотек на более мелкие.

                                                                        В случае с примером, описанным Akon32, библиотека A разбитая на библиотеки Ab, Ac и Ad — это одна библиотека. Все зависимости в данном случае должны быть едиными и иметь общую версию. Кроме того, версия библиотек Ab, Ac и Ad тоже должна быть общей, даже при выпуске новой версии где изменения коснулись только одной части. Если придерживаться этих правил проблем с зависимостями точно не прибавится.
                                                                  0

                                                                  При этом транзитивных зависимостей будет меньше только в теории. На практике же, если библиотека A тоже пошла этим путем, то Ab будет зависеть не от E, а от Ex, Ey, Ez. Каждая из которых, в свою очередь, будет зависеть еще от 5 микро-библиотек.


                                                                  Получается, что вместо зависимости A –> E, F, G, у меня будет Ab, Ac –> Ex, Ey, Ez, Fp, Fq -> *

                                                                    0
                                                                    На практике же, если библиотека A тоже пошла этим путем, то Ab будет зависеть не от E, а от Ex, Ey, Ez.

                                                                    Если E пошла тем же путём, возможно, что в зависимости Ab можно прописать только Ex, а не все Ex, Ey, Ez, поэтому ни Ey и Ez, ни их зависимости грузиться не будут; и т.д.
                                                                    На практике может быть и так, что нужны все Ex, Ey, Ez, и тогда преимущества такого способа нет.

                                                                      +1

                                                                      Вот на практике и получается 13000 зависимостей.

                                                                        0
                                                                        Скорее это комбинация отрицательных моментов первого и второго подхода, когда низкоуровневые библиотеки мелкие, а чем выше, тем больше «функциональности». В итоге и подключено лишнего, и количество зашкаливающее.
                                                                  +2

                                                                  Теоретически да, практически — далеко не всегда.


                                                                  • Во-первых, поскольку нет единообразия, и учитывая, что для решения одной задачи уже существуют как правило несколько альтернатив на выбор, многие транзитивные модули будут зависеть от разных библиотек, предоставляющих один и тот же функционал.
                                                                  • Во вторых, транзитивные зависимости могут тащить разные версии одной библиотеки, и привести все это к общему знаменателю — серьезная проблема. Например производители дистрибутивов Linux или метафреймворков типа Spring Boot как раз решают эту проблему, унифицируя в каждой версии платформы большинство зависимостей.

                                                                  С другой стороны проблемы не в размере самих библиотек, а в том, что современные технологии неприспособлены для автоматического dead code elimination. В сях все было просто: неважно сколько библиотек ты подключил — линкер урежет все, что статически недосягаемо из main(), делая очень компактный бандл. В других языках как Java, Python, JS пришлось искусственно городить модульную систему и требовать от пользователя каждый раз въявную указывать компоненты, которые он будет использовать. Так что это по большей части шаг назад.

                                                                    +4
                                                                    В сях все было просто: неважно сколько библиотек ты подключил — линкер урежет все, что статически недосягаемо из main(), делая очень компактный бандл. В других языках как Java, Python, JS пришлось искусственно городить модульную систему и требовать от пользователя каждый раз въявную указывать компоненты, которые он будет использовать. Так что это по большей части шаг назад.

                                                                    Угу, угу. И каково там управлять зависимостями на C? И что делать, если у двух зависимостей общая транзитивная зависимость, но разных версий?

                                                                      +2
                                                                      • Во-первых, стек библиотек, поставляемый с платформой (версией ОС, SDK, etc), как правило всегда унифицирован транзитивно.
                                                                      • Во-вторых, есть требование, чтобы библиотеки с одной и той же major version были обратно совместимы. http://www.sourceware.org/autobook/autobook/autobook_61.html В этом случае можно просто слинковать более свежую библиотеку.
                                                                      • И в-третьих, в одном бандле можно использовать транзитивные библиотеки разных версий. Для этого линкер должен включить номер версии в таблицу символов.
                                                                        https://blog.habets.se/2012/05/Shared-libraries-diamond-problem.html
                                                                        0
                                                                        • Во-первых, стек библиотек, поставляемый с платформой (версией ОС, SDK, etc), как правило всегда унифицирован транзитивно.

                                                                        Но не все зависимости в этот стек входят.


                                                                        • Во-вторых, есть требование, чтобы библиотеки с одной и той же major version были обратно совместимы. http://www.sourceware.org/autobook/autobook/autobook_61.html В этом случае можно просто слинковать более свежую библиотеку.

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


                                                                        • И в-третьих, в одном бандле можно использовать транзитивные библиотеки разных версий. Для этого линкер должен включить номер версии в таблицу символов.
                                                                          https://blog.habets.se/2012/05/Shared-libraries-diamond-problem.html

                                                                        Окей, это интересно (нет, серьёзно), но что делать с зависимостями, которые линкуются статически? И да, в других языках это просто работает, без дополнительных телодвижений со стороны программиста.

                                                                          0
                                                                          это просто работает

                                                                          Просто это работать не может. Если есть цепочка A-B-D1 и А-С-D2 и нужно объект из библиотеки D передавать между функциями из B и С. Как это сделать?


                                                                          Если же библиотеки D1 и D2 не торчат наружу, то возможно конкретная реализация в Си немного тупая. Но в целом решение очевидное.

                                                                            0
                                                                            Просто это работать не может. Если есть цепочка A-B-D1 и А-С-D2 и нужно объект из библиотеки D передавать между функциями из B и С. Как это сделать?

                                                                            Если вы не указали, чтобы B и C использовали одну и ту же версию — никак, у вас объект из библиотеки D разных версий, т. е. фактически разных библиотек.

                                                                            0
                                                                            Окей, это интересно (нет, серьёзно), но что делать с зависимостями, которые линкуются статически?

                                                                            Я не разрабатываю на Си, но насколько я могу судить (да поправят меня знающие люди), нет большой разницы слинкована библиотека динамически или статически. Любое приложение можно слинковать обоими способами (чем пользуются всякие flatpack и snappy). В первом случае резольвинг идет в рантайме на этапе загрузки бандла, тогда как во втором — сразу на этапе линковки бандла. Правила резольвинга не должны отличаться.


                                                                            Или просто в новой версии транзитивной зависимости добавили новую функцию, которая имеет то же имя, что и в библиотеке.

                                                                            Когда говорят о транзитивных зависимостях, почему-то нигде не указывают тип транзитивности. Вне зависимости от языка программирования любая библиотека всегда состоит из двух частей: интерфейса (структуры, типы, сигнатуры функций) и имплементации (непосредственно код). Интерфейс библиотека экспортирует наружу, тогда как имплепентация — это внутреннее поведение библиотеки. Если транзитивная зависимость используется полностью в имплементативной части библиотеки, то нет никаких проблем иметь разные версии в разных зависимостях: различные платформы предоставляют свои средства "изоляции" (namespaces, dynamic linkers, classloaders, etc...).


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


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

                                                                              0
                                                                              Если транзитивная зависимость используется полностью в имплементативной части библиотеки, то нет никаких проблем иметь разные версии в разных зависимостях: различные платформы предоставляют свои средства "изоляции" (namespaces, dynamic linkers, classloaders, etc...).

                                                                              Только не в C, там из средств изоляции только static для функций.

                                                                                0
                                                                                > Я не разрабатываю на Си, но насколько я могу судить (да поправят меня знающие люди), нет большой разницы слинкована библиотека динамически или статически.

                                                                                Тут таки сложнее. В Windows, например, статические библиотеки линкуются как внутрь основного бинарника, так и внутрь DLL (это долго относилось, а может, и сейчас, к CRT — C runtime library); если статическая библиотека это не импорт DLL, то каждая DLL получит свою копию этой статической, со своей версией и своими глобальными переменными. Поэтому лучше, например, malloc/free/new/delete делать переходниками на соответствующие функции user32, если нет жёстких причин делать иначе; если же рантаймы у двух DLL различаются, то возникает жёсткое правило что освобождать память должна та же DLL, что её аллоцировала.

                                                                                В Unix, соответствующие уровни обычно сделаны в общей libc, а в общем случае подключается только одна библиотека (самая свежая) каждого типа, но и там можно при желании натворить хаков — статическая линковка внутрь SO, прямой dlopen на желаемую библиотеку, и прочая и прочая.

                                                                                > Вне зависимости от языка программирования любая библиотека всегда состоит из двух частей: интерфейса (структуры, типы, сигнатуры функций) и имплементации (непосредственно код). Интерфейс библиотека экспортирует наружу, тогда как имплепентация — это внутреннее поведение библиотеки.

                                                                                Теоретически — да. Практически же этот механизм приводит к тому, что ссылка двух DLL друг на друга по кольцу без явного резолвинга в коде уже ломает всё, и аналогично для .a (.lib).
                                                                                Деление на интерфейс и реализацию в этой схеме совершенно нетипично, это не классовая иерархия.
                                                                        0
                                                                        Это в теории. В практике 99% разработчиков будут писать что-нибудь типа «include *», а то мучаться, выбирать нужные библиотеки… Сразу все включить и не мучаться ((
                                                                          0

                                                                          include * не значит что используется всё. компилятор может знать что используется а что нет. А вот какой то __import__(random_string()) в интерпретируемых языках это уже хуже.

                                                                        0
                                                                        … Вот поэтому нужно развивать инструменты, которые позволят вырезать ненужный мусор (aka стриппинг). Не актуально для плюсов, но зато будет актуально для всех скриптовых языков.
                                                                          0
                                                                          Это тот путь, который давным давно есть в perl.
                                                                          +15

                                                                          "Нужно оптимизировать ПО" — весьма банальная идея.
                                                                          Программы, в которых действительно нужна скорость, и так тщательно оптимизируются.
                                                                          Но есть и такие программы (и их много), где не важно, 100 или 200 миллисекунд будет обрабатываться нажатие кнопки. А процесс оптимизации — это некоторые затраты.


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

                                                                          В ряде случаев это, конечно, хорошая идея, но постоянная память сегодня практически ничего не стоит. Какая-нибудь SD карта размером с ноготь может хранить сотни гигабайт. Нет смысла беспокоиться, пока система не начнёт работать настолько плохо, что за неё станет стыдно (или пока конкуренты не прижмут). Если 100500МБ библиотек перестали влезать в SSD — определённо, надо что-то делать.
                                                                          Ну и собственно разделение библиотек может быть хорошей идеей по ряду других причин, не связанных с объёмом исполняемого кода, например уменьшение вероятности некоторых конфликтов зависимостей.

                                                                            +11
                                                                            Проблема в том, что у разработчиков ПО обычно топовые компьютеры с кучей памяти, быстрыми многоядерными процессорами и быстрыми дисками. И быстрый интернет. Особенно быстрый канал связи до своих серверов. У них всё работает быстро и без тормозов. А у пользователей разные компьютеры, в том числе старые и тормозные.
                                                                            Если предложить разработчику поработать на старом нетбуке с процессором Atom и двумя гигами оперативки и подключить его через ADSL, то наверняка он сразу задумается об оптимизации своего софта. И не только своего.
                                                                              +20

                                                                              Проще: оптимизация начнется, как только стоимость разработки станет меньше стоимости железа.

                                                                                +1
                                                                                Проблема в том, что стоимость разработки должна стать меньше, чем стоимость железа у разработчиков, а не у пользователей. Я собственно про то и написал — что как только стоимость железа станет такой, что разработчики вынуждены будут сидеть на устаревшем железе, тогда они и будут оптимизировать.

                                                                                Проблемы пользователей разработчиков не волнуют. По крайней мере проблемы 10-20% пользователей с наиболее слабым железом. Они кассу не делают.
                                                                                  0
                                                                                  Это не правда. Если разработчики поставляют ПО, которое у пользователей (проблемы которых, якобы, программистов не волнуют) тормозит, пользователи уходят к другим поставщикам софта. Тогда к программистам приходит менеджмент и их начинают волновать другие проблемы.
                                                                                    +2
                                                                                    К какому поставщику ушли пользователи винды, ютуба, или гугломейла? (вопрос риторический)
                                                                                      0

                                                                                      Благо, ютуб пока что ещё смотрится через mpv, а в гугломейле не отрезали классический HTML-вид, но это пока :-)

                                                                                        +1
                                                                                        А другого софта нет? Я работаю в ЕРП и у нас такое случается — клиент может громко хлопнуть дверью. Просто тут каждый клиент стоит как сотня клиентов в виндовзе. А ютюб и гугломейл вообще бесплатные.
                                                                                        +1
                                                                                        пользователи уходят к другим поставщикам софта


                                                                                        … с новым глюкодромом и тормозами. А от «другого» поставщика переходит кто-то к первому, лелея мрию что тут ему сделают красиво :)
                                                                                        +13

                                                                                        Повторюсь: оптимизация начнется, когда стоимость разработки станет меньше стоимости железа.


                                                                                        Объясню: большему числу пользователей примерно наплевать на производительность — они всё равно будут пользоваться.


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


                                                                                        А на коленке разработать супер-пупер скоростной "скайп" с групповыми видеозвонками и не жрущий оперативку ведрами можно. Да, вот только продавать его будут уже твои внуки, если он вообще кому-то нужен будет.


                                                                                        А в это время твой конкурент нафигачит "хренак-хренак и в продкашен" звонилку с webrtc, люди успеют им попользоваться (ну и поплеваться, конечно же), с них успеют постричь деньги, после чего он станет немодным и уйдет в забвение.


                                                                                        Любой серьёзный софт с хорошей оптимизацией — это, зачастую, десятки человеколет, либо bus factor == 1 (Умирает человек — умирает проект, как будет когда-нибудь с foobar2000, к примеру, потому что с его кодом практически никто не знаком. Максимум — растаскают по разным плеерам).


                                                                                        Ни у одного идеалистичного разработчика нет денег, чтобы десятки человеколет превратить в год календарного времени. А те, у кого есть — умеют считать деньги и не будут страдать такой фигнёй, а превратят x1 капитала в x2 по старой схеме.

                                                                                          +4
                                                                                          Повторюсь: оптимизация начнется, когда стоимость разработки станет меньше стоимости железа.

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

                                                                                            0
                                                                                            Вот неистово плюсую.
                                                                                            В современном мире оптимизацией, как правило, начинают заниматься только тогда, когда этого уже ну никак нельзя избежать. Когда производительность оказывается абсолютно неприемлемой.
                                                                                            Это доведенный до крайности принцип «решать проблемы по мере их поступления».
                                                                                              +3

                                                                                              Напомнило историю из одной фирмы, где писали на плюсах и имели свой собственный аналог npm (для плюсов) с кучей зависящих друг от друга библиотек. Там о библиотеках и оптимизации начали задумываться тогда, когда на одной из платформ линкер упёрся в ограничение по потребляемой памяти от ОС.


                                                                                              Начинать утро с того, чтобы добавить новые транзитивные зависимости в свой мейкфайл ручками (потому что более адекватной системы управления зависимостями не было, и транзитивные зависимости надо было перечислять явно) — регулярно было. Чтобы это делать не ручками, была даже специальная утилита, которая запускалась на билдферме и пыталась слинковать код, последовательно добавляя в него новые библиотеки, пока не исчезнут неопределённые символы, но у неё были свои проблемы.

                                                                                                0

                                                                                                А можно ликбез зачем линкеру столько памяти? Казалось бы ему надо примерно столько, сколько будет весить итоговый бинарник. Развен он строит какое то дерево зависимостей по ходу дела?

                                                                                                  +2

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


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


                                                                                                  Так что npm с его 13 тыщами зависимостей для тудушки и гигабайтами на диске — это ерунда и детский лепет по сравнению с Ъ тырпрайзным сиплюсплюс.

                                                                                                    0
                                                                                                    не у линкера не хватало памяти, а у самого получающегося бинаря — ОС не могла его загрузить, потому что слишком много туда было влинковано, и оно тоже выходило за какие-то пределы

                                                                                                    Банальный виндовый exe (PE) не может быть больше 2ГБ. Лимиты ближе, чем кажутся. Я видел dll от nvidia размером в несколько сотен МБ.

                                                                                                      0
                                                                                                      xul.dll из Mozilla Firefox весит 107 метров. Надо будет дома посмотреть, думаю, у игрушек можно найти бинари и побольше.
                                                                                                        +1
                                                                                                        Самые большие бинари — это самораспаковывающиеся архивы. А у игрушек обычно компактный движок в виде exe или dll и гигабайты ресурсов лежат рядом.
                                                                                                          0
                                                                                                          У игрушек — возможно. Потому что там этих ресурсов слишком много и они регулярно обновляются. А вот у «обычных» подвиндовых программ как раз исполняемые файлы, включая DLL, используются в качестве контейнеров для хранения ресурсов.
                                                                                                          0
                                                                                                          Если я правильно помню, как происходит работа с динамическими библиотеками, то в память загружается только инициализирующий код, а остальное подтягивается по мере необходимости. Ну и у виндовых исполняемых файлов, в том числе у DLL, зачастую, основной объём — ресурсы, которые в *nix-ах в исполняемых файлах не хранятся, а лежат «рядом» отдельными файлами картинок и прочего подобного.

                                                                                                          То есть это вопрос не того, что непонятно чего накодировали, а использования DLL в качестве «коробочки» для хранения картинок и чего-то там ещё.
                                                                                                  0
                                                                                                  А конкуренция — это как раз про отзывы пользователей. Точнее, про то, что пользователям надоедает, что их отзывы сливаются в канализацию и они уходят к конкурентам. То есть это одно и то же, в общем-то, только на разных стадиях.
                                                                                                  –2

                                                                                                  Извините, ваша теория разбивается об энергопотребление современного железа.
                                                                                                  Людям нужно чтобы ноутбук держал 5-10 часов. У нас есть работающая, но тормозящая программа. Пользователи пользуются. Но как только конкурент сможет предоставить более энергоэффективный аналог, это станет решающим фактором для части пользователей.
                                                                                                  На десктопе отличие в том что сейчас счет пошел на сотни ватт. Пользователи не будут ставить чиллер чтобы пользоваться ПО про которое пишите вы.

                                                                                                    +4

                                                                                                    Хорошо, как давно Вы ставили последний раз ПО исходя из этого?


                                                                                                    А если, к примеру, я предложу Discord с показателем потребления /10, но за подписку 5$/месяц? Подскажу: скорее всего, большинство соберется купить себе ноут подороже и с большей батареей или проц пошустрее, чем отдать 3-5$ за ПО, если у него есть тормозные бесплатные альтернативы. Ну просто потому, что "незачем отдавать этому производителю ПО бабло просто потому, что соседнее ПО один хрен цпу/рам выжрет, а если покупать каждое — проще новый проц поставить".


                                                                                                    Всё всегда упирается в деньги. И Ваши претензии тоже. Ибо пока тормоза не начнут бесить на топовом ноутбуке, вас не будут волновать проблемы индейцев на нетбуках. И т.д. И вы не будете платить за оптимизацию такого софта (проблема вас не касается, а платить за других — не принято). А у индейцев — скорее всего денег тупо нет платить за оптимизацию такого софта.


                                                                                                    Могу даже упростить: можете показать выписку с донатами Mozilla (если Вы ей пользуетесь), Canonical (если пользуетесь Ubuntu), Eclipse Foundation (если пользуетесь Eclipse IDE)?


                                                                                                    Если нет — то какие вопросы?

                                                                                                      0

                                                                                                      Могу привести пример — Скайп. Когда-то безальтернативное решение, и один из сейчас. Последние несколько лет в связи с деградацией производительности точно потерял часть рынка.


                                                                                                      А как вы решите деньгами разряжающийся за 2 часа ноутбук на core i7 8 поколения?


                                                                                                      можете показать выписку с донатами Mozilla (если Вы ей пользуетесь), Canonical (если пользуетесь Ubuntu), Eclipse Foundation (если пользуетесь Eclipse IDE)?

                                                                                                      Давайте без выписки. Если вам интересно, поддерживал и поддерживаю свободное ПО как Ubuntu, phpmyadmin и прочие линуксы. Буквально несколько дней назад отправил 10$ Википедии.
                                                                                                      Вы правы, я буду платить за быстрое ПО.

                                                                                                        0

                                                                                                        Скайп — опровержение вашей теории о "решающем факторе". Да, он теряет пользователей из-за тормознутости и глючности. Но вы сами можете видеть, что теряет он их недостаточно быстро. То есть на практике этот фактор влияет не особо сильно (хорошо хоть влияет). Любой тормознутый софт может годами использоваться десятками миллионов пользователей.

                                                                                                          0
                                                                                                          У Скайпа, если МС окончательно его не решили угрохать, есть до сих пор киллерфичи — полноценные десктопные клиенты на разные плафтормы, аудио и видео в режиме конференций, показ экрана, режим редактора кода вроде был.
                                                                                                          Даже у более успешных конкурентов или чего-то нет или что-то неполноценное неудобное или что-то, что в Скайпе второй десяток лет, завозят вот только что.
                                                                                                            0
                                                                                                            Скайп — не самый лучший пример, пожалуй. Всё-таки то, что им продолжают пользоваться, связано с тем, что на него завязана клиентская база. То есть, если сейчас LibreOffice начнёт портиться, я переползу на другой офисный пакет и меня это не напряжёт. Но вот что мне делать с кучей потенциальных клиентов, которые особо жаждут менять Скайп на что-то ещё? То есть я бы и перешёл, но «клиент всегда прав». Платёжеспособный клиент, разумеется. Но чтобы добраться до стадии, когда начинаешь интересоваться платёжеспособностью, надо ещё с ним связаться. А это — Скайп. Да, есть Телеграм. За последнюю пару лет он стал достаточно популярным, чтобы начали запрашивать уже его, но Скайп всё равно остаётся где-то в топе, а мне приходится из-за него страдать, потому что кривой и падает.
                                                                                                              0

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


                                                                                                              Так же что Скайп, к сожалению, хороший пример. Пока 80% готовы мириться с плохой скоростью ПО, остальные 20% тоже будут. Скорость — не определяющий фактор.

                                                                                                                0
                                                                                                                Нет, как раз поэтому Скайп — неудачный пример: выбор делает не один человек, а сообщество пользователей. И если офисный пакет, браузер, почтовый агент я могу менять хоть три раза на дню и ни от кого этот выбор зависеть не будет, то со средствами общения с закрытыми протоколами всё сильно хуже, потому что они завязывают пользователя на сообщество, которое использует это средство связи. И да, пока Скайп не осточертее достаточно большому количеству пользователей, таким, как я, кто использует Скайп для связи с клиентами, никуда с него не деться. Потому что клиент хочет использовать Скайп, а мне приходится подстраиваться. Раньше это был ICQ, к которому я в какой-то момент с смог подключиться и удалил аккаунт, потому что уже несколько лет мне на него никто не писал. Через какое-то время, видимо, та же судьба постигнет и Скайп, а потом и Телеграм, у которого своих косяков хватает. Например, врождённый недостаток — регистрация по номеру телефона, то есть завязка безопасности на сторонний сервис, потенциально подконтрольный враждебным структурам. А уже есть дыра в безопасности размером с корабль.
                                                                                                                  0
                                                                                                                  Например, врождённый недостаток — регистрация по номеру телефона

                                                                                                                  А все современные популярные сервисы так регистрируются. И никто это не будет исправлять, потому что персональные данные им важнее, чем безопасность пользователей.
                                                                                                                    0
                                                                                                                    Дискорд прекрасно работает без номера телефона. Более того, он позволяет использовать 2FA без привязки телефона, что особенно радует.
                                                                                                                    0
                                                                                                                    офисный пакет

                                                                                                                    Если файлы сложные — не можете. У ваших клиентов просто поедет всё, придётся вам потерпеть. Если файлы простые, то повезло.


                                                                                                                    браузер

                                                                                                                    Не можете. Движка осталось, фактически два, более одного раза не поменяете. Скины к хрому не в счёт, их вы правда можете менять.

                                                                                                              +1
                                                                                                              деградация производительности скайпа ерунда по сравнению с отвратительной работой на мобильных. Показать что мне пришло сообщение с опозданием на несколько часов или не показать вовсе — вот что для меня полностью убивает его как мессенджер.
                                                                                                                0
                                                                                                                А вот это, как я понимаю, косяк служб Google (если Вы про него, а не про iOS) или чего-то на этом уровне, потому что уведомления не приходят не только в Скайп. Причём, на старом смартфоне с Android 5.1 всё работает на ура. Но да, на смартфоне он тормозной. По крайней мере, это сильно заметно, если смартфон не тягается по производительности с дэсктопом.
                                                                                                                  0
                                                                                                                  Там закрутили гайки, да, но пуши вполне себе работают, если их уметь правильно готовить.
                                                                                                                    0
                                                                                                                    Ну вот из всего, что стоит у меня, адекватно пуши работают только у WhatsApp, который используется вынужденно, и у GMail, у которого до недавнего времени так же были с этим проблемы.
                                                                                                                +1

                                                                                                                Скайпом перестали пользоваться не из-за деградации производительности, а из-за деградации качества самого приложения — глюки, реклама, убогий UX, И так далее.

                                                                                                                0
                                                                                                                А если, к примеру, я предложу Discord с показателем потребления /10, но за подписку 5$/месяц?
                                                                                                                На самом деле, цены на freemium-софт сильно завышены, потому что каждый покупатель подписки платит за себя и того парня взвод других парней. Помню, несколько лет назад писали, что у Evenote платят только 4% пользователей. Может быть, сейчас иначе, но тем не менее.
                                                                                                                Так вот если заставить платить всех без исключения, то 5 баксов в месяц могут легко и непринужденно превратиться в 5 баксов в год :)
                                                                                                                  0

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


                                                                                                                  Можете для эксперимента предложить пенсионерам заплатить 5$ в год за подписку на видеозвонилку в дополнение к интернету, когда у них уже есть скайп. Заодно словарный запас можно пополнить, у пенсионеров опыта бывает много.


                                                                                                                  В общем, мы платим за то, что можем себе позволить. И позволить себе весь фоновый софт на компе я думаю, не смогу. Денег и единомышленников не хватит.

                                                                                                                    +1

                                                                                                                    Заставить? Какая классная идея, модная, современная.

                                                                                                                      0
                                                                                                                      Да нет, идея стара как мир. За колбасу, ботинки и такси платят все, а не некоторые.
                                                                                                                        0
                                                                                                                        За… такси

                                                                                                                        Раз в год частнику на пляж скататься.
                                                                                                                          +1

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

                                                                                                                            0
                                                                                                                            Никакое «заставить платить» тут быть не может.

                                                                                                                            Винда же (если без пиратства). Да, есть линуксы, но сидя на работе под линуксом, дома поставил винду, потому что даже в steam из всех игр что у меня куплены — в линь умеют процентов 10 от силы. Плюс под винду написана просто масса по, которого нет под линь, а аналоги… Вот чем заменить мс офис именно при серьёзном документообороте? openoffice, libreoffice — простые документы обычно норм, но сложные, со сложным форматированием, с режимом комментирования — ломаются в 90+% случаев. То нумерация уплывает, то страницы рвутся криво, то вёрстка уезжает и иногда это важно… Мы пытались использовать и линухи и *офисы, но по моему субъективному опыту — самым стабильным был ooo 2.2 (выпущенное году этак 2010, последний раз сравнивали году в 2015), а либра била доки даже те, которые в ооо 2.2 показывались как надо.
                                                                                                                            И это при том что режим правок например терялся полностью. Итог — внутри фирмы — ООо, всем кто общался с клиентами и вообще с миром — винда и мс офис.
                                                                                                                            Возможно, мак был бы решением, там вроде как есть и мс офис и ещё много софта, но он сам по себе дороже и это отдельная экосистема.
                                                                                                                              0
                                                                                                                              простые документы обычно норм, но сложные, со сложным форматированием, с режимом комментирования
                                                                                                                              Вот никогда не понимал, а зачем нужны «сложные» доковские документы. Либра рецензирование, формулы и ссылки вполне себе вывозит в 5 версии.
                                                                                                                                0
                                                                                                                                Вот никогда не понимал, а зачем нужны «сложные» доковские документы. Либра рецензирование, формулы и ссылки вполне себе вывозит в 5 версии.


                                                                                                                                Внутри себя вывозит.
                                                                                                                                При импорте-экспорте — съезжает форматирование.
                                                                                                                                  0
                                                                                                                                  У кого как :)
                                                                                                                                    0
                                                                                                                                    У кого как :)

                                                                                                                                    Не у кого, а у чего.
                                                                                                                                    Зависит от самого документа.

                                                                                                                                    Причем съезжает форматирование и у элементарных вещей типа «выставить счет в OpenOffice и открыть в Excel или наоборот».

                                                                                                                                    А счет это такая простейшая форма:

                                                                                                                                    image

                                                                                                                                    Вы можете предположить, что съезжает картинка с печатью или подписью?

                                                                                                                                    Нет, съезжают рамки и то что в рамках написано.
                                                                                                                                    Сталкиваюсь довольно часто.
                                                                                                                                      0
                                                                                                                                      В смысле ширина ячейки в docx? Кстати, это скорее всего связано с тем, что по-разному в ОО и Офисе ставится якорь картинки, поэтому для портабельности я стараюсь по максимуму верстать таблицами с невидимыми границами.
                                                                                                                                        0
                                                                                                                                        это скорее всего связано с тем, что по-разному в ОО и Офисе ставится якорь картинки

                                                                                                                                        Написано же — дело не картинке.
                                                                                                                                          0
                                                                                                                                          Нет, написано, что съёзжает не картинка. Якорь может сбивать позиционирование полей и границ других элементов. Я с этим сталкивался, когда документ из 2007 перекосило в 2003, долго рассуждал о неочевидности решения инвективной лексикой.
                                                                                                                                            0
                                                                                                                                            Нет, написано, что съёзжает не картинка. Якорь может сбивать позиционирование полей и границ других элементов. Я с этим сталкивался, когда документ из 2007 перекосило в 2003, долго рассуждал о неочевидности решения инвективной лексикой.


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

                                                                                                                                            Ну ОК. Ровно такой файл, состоящий из надписей и рамок имеет нередко ровно такие же проблемы.
                                                                                                                                            Без картинок.
                                                                                                                                              0
                                                                                                                                              docx или doc?
                                                                                                                                                0
                                                                                                                                                docx или doc?

                                                                                                                                                Новый, конечно же.
                                                                                                                                                  0
                                                                                                                                                  Тогда лажа, да. И тут не важно, кто неправильно реализует стандарт.
                                                                                                                                  0
                                                                                                                                  Да просто договор, где описаны пункты которые нужно сделать. В оригинале был пункт 10.20, стало 11.2 — из постоянно встречающегося.
                                                                                                                                  Берём сложнее. ТЗ. То есть документ, с которым работают обе стороны. И тут история правок и «совместная работа» это жизненно важно. Да, сейчас берём тот же гугл докс и не знаем бед, но суть была именно в локальном редакторе.
                                                                                                                                  Ну и всякие рамки ползут даже в простых доках, это да.
                                                                                                                          0
                                                                                                                          Бесплатные пользователи наполняют базу, они жизненно необходимы любому софту с социальным взаимодействием. Никто бы не пользовался дискордом, если бы в нём сидели только люди с платными аккаунтами. С ПО которое не зависит от базы пользователей, естественно, ситуация другая — но там зачастую и нет бесплатной модели, либо она урезана ровно настолько, чтобы показать пользователю фичи и подвести к покупке.
                                                                                                                          0
                                                                                                                          Отчасти эту проблему можно разрешить изменением культуры. Да, пользователи практически никогда не сравнивают производительность программ выбирая, чем будут пользоваться (но я вот например сравнивал), просто потому что на это нужно много сил.

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

                                                                                                                          Хотел бы я, чтобы обзоров с измерениями было больше.
                                                                                                                            0
                                                                                                                            Я уже устал спорить. Я и сам заинтересован в быстром ПО, но, надо признать, силёнок у нас маловато лоббировать и продвигать свои интересы.

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

                                                                                                                              Вот по крайней мере для России.
                                                                                                                              Есть госреестр отечественного по.
                                                                                                                              И если будут включены требования по скорости, хотя бы по скорости отклика и по памяти.
                                                                                                                              Разработчики вынуждены будут изменить по, для включения в данный реестр.
                                                                                                                                0
                                                                                                                                Владельцы кампаний занесут куда надо для включения. Пока половина ПО в данном реестре в принципе никак не соответствует его требованиям.
                                                                                                                                  0
                                                                                                                                  И если будут включены требования по скорости, хотя бы по скорости отклика и по памяти.
                                                                                                                                  Разработчики вынуждены будут изменить по, для включения в данный реестр.

                                                                                                                                  Какая "интересная" идея. Ресурсоёмкое ПО сразу вылетает из реестра. Остальные пишут костыли, чтобы удовлетворить формальным требованиям.
                                                                                                                                  А когда железо подешевеет, ПО его не может использовать, потому что законодательно будет ограничено лимитом, аналогичным "640кБ". Развитие приостановится.


                                                                                                                                  Имхо, вместо этого лучше пролоббировать "разработчики обязаны ходить строем". Это сократит время на перемещения и просто красиво (по мнению некоторых).

                                                                                                                                0
                                                                                                                                Отчасти эту проблему можно разрешить изменением культуры
                                                                                                                                Или, другими словами — невозможно.
                                                                                                                                  0
                                                                                                                                  Разве нет примеров изменения культуры? Почему культура потребления ПО не относится к таким культурам, в которых возможны изменения?
                                                                                                                                –1

                                                                                                                                Тут есть много факторов, скорость удобство цена, но потребление батареи у меня один из ключевых. Особенно на телефоне, где каждый калькулятор норовит висеть в бэкграунде и сливать телеметрию все сутки на пролет. Зоопарк мессенджеров это вообще идиотизм. Скайп на компе включаю только если надо позвонить по видео и потом сразу выключаю.
                                                                                                                                Да блин я бы хоть сейчас задонатил бы на хабр если бы они наконец убрали поыиксиили тормознутые комментарии, и сделали бы полноценную мобильную версию.

                                                                                                                                  0
                                                                                                                                  Скайп на компе включаю только если надо позвонить по видео и потом сразу выключаю.

                                                                                                                                  У вас какая-то эгоистично-односторонняя связь получается. А если кому-то другому надо позвонить вам с видео — что делать? Связываться с вами по другому каналу связи и нижайше просить вас включить скайп?
                                                                                                                                  Ну и второй вопрос — если для вас решающим фактором является энергопотребление — зачем выключать скайп на десктопе?
                                                                                                                                    0

                                                                                                                                    Так происходит что о видео звонках договариваемся заранее, я же не в калл центре работаю. Речь про ноут.

                                                                                                                                      +1
                                                                                                                                      А если кому-то другому надо позвонить вам с видео — что делать? Связываться с вами по другому каналу связи и нижайше просить вас включить скайп?

                                                                                                                                      Да, а это плохо?


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


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

                                                                                                                                        0

                                                                                                                                        Ну Ops и SRE не могут позволить себе такой роскоши как выключенный телефон )

                                                                                                                                          0

                                                                                                                                          Ops и SRE не получают звонки на скайп (я надеюсь) и могут себе позволить условный PagerDuty.


                                                                                                                                          Впрочем, on-call duty с минутным SLA 8 часов в день, 7 дней в неделю, при работе программистом всякой HFT-дряни на прошлой работе — это была основная причина, почему я оттуда хотел уходить.

                                                                                                                                +2

                                                                                                                                Тоже так думаю. Идеальный пример Whatsapp и и Telegram. Первый вышел на рынке раньше и сейчас является монополистом практически, на фоне телеграмма, который уделывает его по всем параметрам, но большинство, как пользовалось whatapp, так и пользуется. Кроме тех людей, которые попробовали telegram конечно...

                                                                                                                                  +1
                                                                                                                                  Телега очень долго не имела собственно связи, это был мессенджер.
                                                                                                                                  Вацап — это вполне себе интернет-телефон и видеофон с самого начала.
                                                                                                                                    0
                                                                                                                                    Вацап — это вполне себе интернет-телефон и видеофон с самого начала.

                                                                                                                                    Это не так. Изначально WhatsApp был заменой SMS и ничего кроме сообщений не умел. И причём был платным.

                                                                                                                                    Первый выпуск приложения относится к январю 2009 года. К апрелю 2012 года ежедневно при помощи WhatsApp пересылалось 2 миллиарда сообщений, более 10 миллиардов в августе 2012 года, более 27 млрд в июне 2013 и более 50 млрд сообщений на март 2015. В феврале 2018 около 1 млрд человек отправляли через WhatsApp 55 млрд сообщений в день.
                                                                                                                                    По мнению, опубликованному в газете Financial Times, приложение WhatsApp сделало с SMS то же, что сделала программа Skype с международными телефонными звонками.

                                                                                                                                    В феврале 2014 года CEO WhatsApp намекнул, что к лету планируется добавить функциональность VoIP-звонков между пользователями, и в конце марта 2015 года эта функция была реализована на платформе Android. В апреле 2015 года звонки появились на платформе iOS. В июне 2015 года функция стала доступна владельцам Windows Phone.

                                                                                                                                    19 февраля 2014 года компания Facebook Inc. объявила о приобретении WhatsApp за 19 млрд долларов.
                                                                                                                                    WhatsApp стал бесплатным с 18 января 2016 года. Ранее за подписку на использование сервиса взималась плата в размере около 1 доллара США каждый год, начиная со второго года использования, либо (для платформ Apple), однократный платёж при покупке приложения

                                                                                                                                    К 2015 году WhatsApp стал самым популярным приложением для обмена сообщениями в мире, и по состоянию на февраль 2020 года в нем насчитывалось более 2 миллиардов пользователей. WhatsApp стал основным средством электронной связи во многих странах и регионах, включая Латинскую Америку, Индийский субконтинент и большую часть Европы и Африки.


                                                                                                                                    Пользовался и телеграмом и вотсапом на смартфоне, не вижу, чем именно телеграм лучше.
                                                                                                                                      0

                                                                                                                                      Личный взгляд на преимущества и недостатки зависит от сценариев использования. Для меня, например, Telegram бесспорно выигрывает и вот почему:


                                                                                                                                      1. Максимальный размер файлы в WhatsApp — 16Mb (с ограничениями по типу файлов, старые файлы удаляются с сервера), в Telegram — 2Gb (без ограничений на тип файла, старые файлы не удаляются и их всегда можно скачать)
                                                                                                                                      2. Максимальное число участников в группе WhatsApp — 256, в Telegram — 200000
                                                                                                                                      3. Хорошие боты: в Telegram они есть
                                                                                                                                      4. В Telegram можно можно сохранять сообщения для самого себя, никому их не отправляя
                                                                                                                                        0

                                                                                                                                        Ага т.е. он стал бесплатен после покупки фейсбук. Что они от этого выиграли? Куда идет телеметрия и какая, является ли проект дотационным?) С телегой тот же вопрос. Или телега ещё на стадии пилим деньги инвесторов?

                                                                                                                                          0
                                                                                                                                          Или телега ещё на стадии пилим деньги инвесторов?

                                                                                                                                          А там разве были инвесторы? Вроде Паша пилит свои личные деньги. По крайней мере такое ощущение у меня создалось.
                                                                                                                                    0
                                                                                                                                    Повторюсь: оптимизация начнется, когда стоимость разработки станет меньше стоимости железа.

                                                                                                                                    Наверное даже так: оптимизация начнется, когда стоимость разработки и поддержки станет меньше дополнительной стоимости/задержек которые пользователи готовы заплатить за более оптимальный продукт, с учетом конкурентных продуктов.
                                                                                                                                    +1
                                                                                                                                    В игровой индустрии очень хорошо все видно. Какие бы мощные компы не были у разрабов, если писать неоптимально, то просто некому будет играть.
                                                                                                                                      +1
                                                                                                                                      Проблемы пользователей разработчиков не волнуют. По крайней мере проблемы 10-20% пользователей с наиболее слабым железом. Они кассу не делают.

                                                                                                                                      Волнуют. В указанных в ТЗ рамках.
                                                                                                                                      А если там например указано (или НЕ указано но сказано неявно) что телефоны с дисплеем меньше N" не поддерживаем — пользователю с таким — не повезло. Если по ТЗ надо при старте приложения показать пользователю продукты которые ну очень будут ему полезны — это и будет сделано.
                                                                                                                                      Если надо сделать приложение «красивее» (пусть даже это значит на определенный период в приложении будет и новый и старый код ) — ну вы поняли.
                                                                                                                                      Если надо «по соображениям безопасности» дергать 3rd party либу которая не только собирает данные все какие может но еще и спамит в logcat при этом (серьезно тормозя при этом работу) — ну значит максимум разработчики сделают возможность собирать версию где эта либа просто не инициализируется. Для себя сделают потому что в прод это выкатывать — «это ж безопасность».
                                                                                                                                      Кэширование? Ну может быть сделаем, но нам же актуальность данных важнее.

                                                                                                                                        0
                                                                                                                                        Не помню точно, в какой корпорации это было, но кажется в Facebook. В общем, там в какой-то момент ввели «день 2G»: раз в неделю разработчикам настоятельно рекомендовали переключать свои убер-мега-топовые смартфоны на 2G, чтобы почувствовать себя «в Африке» и перестать пытаться загрузить видео прямо в шапку главной странице сайта. Последнее я кое-где встречал.

                                                                                                                                        И да, у меня есть старый нетбук с 2 гигами ОЗУ, которого мне долго хватало для разработки, но вот просмотр сайтов он уже давно не тянул, хотя как бы НЕТбук. Последнее время стало получше — Firefox-у всё-таки навели рефакторинг, но всё-таки.
                                                                                                                                          0
                                                                                                                                          переключать свои убер-мега-топовые смартфоны на 2G

                                                                                                                                          Мухаха, мне нужен день 4G, когда я свой убер топовый смартфон наконец-то подключу через 4G вместо на жёсткую выставленного 2G ))
                                                                                                                                            0
                                                                                                                                            Ну ой. У кого щи жидки, у кого жемчуг мелок. Вроде, в областном центре живу, а знаю места в городе, причём, не в жопе мира, где связь сильно так провисает.
                                                                                                                                              0
                                                                                                                                              Да ловит у меня везде отлично, это я так, не пользуюсь мобильным интернетом за ненадобностью и сижу на тарифе по 1,5 рубля за мегабайт и плачу 100 рублей в месяц.
                                                                                                                                      +4
                                                                                                                                      Проблема в том, что у разработчиков ПО обычно топовые компьютеры с кучей памяти, быстрыми многоядерными процессорами и быстрыми дисками. И быстрый интернет.

                                                                                                                                      Проблема в отсутствии тестирования в реальных условиях, а не в хорошем железе. Разработчику, кроме программы, ещё и инструменты разработки запускать надо. Хорошие инструменты довольно требовательны к ресурсам.