Картинка из фильма «Размер имеет значение», 2009

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

Название частично позаимствовано из статьи Никлауса Вирта «Долой „жирные“ программы», которой в 2016г было ровно 10 лет, и актуальности она не утратила — а скорее вышла на новый уровень, кто не знаком — почитайте.

Рассмотрим разные аспекты, влияющие на производительность систем и программ.

Языковой аспект
Аспекты памяти
Аспекты реального мира
Неязыковые факторы
Аспект человеческого фактора

Языковой аспект


а) Влияние языка программирования и компилятора


Как я и говорил ранее в комментариях, использование “хорошего” языка дает приличную разницу в скорости.

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

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

Далее пройдемся по градации между ними.

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

Копии и модифицированные исходники я выложил здесь github.com/Siemargl/FatProgs
Крайними точками отрезка являются оптимизированная С-программа и интерпретируемая Python3.6 программа (не потому, что Питон мне не нравится, но потому что он на предыдущих подобных тестах всем проиграл и является точкой Б, да еще и нужные тесты для него есть уже готовые)

Результаты Dhrystone
>gcc -O2 -DTIME -DHZ= dhry_1.c dhry_2.c -o gcc_dry2

D:\VSProjects\_pl_benchmark\Dhrystone>gcc --version

gcc.EXE (tdm-1) 4.9.2
>gcc_dry2 500000000
User time = 27 sec
Microseconds for one run through Dhrystone: 0.1
Dhrystones per Second: 18518518.0
DMIPS 10539.9
>python.exe pystone.py

Pystone(1.2) time for 5000000 passes = 46.4937
This machine benchmarks at 107542 pystones/second

Разница в скорости в 172 раза. Если посмотреть исходники, то пистоуны это и есть драйстоуны в оригинале.

Для исключения махинаций, возьмем еще TinyC — который не умеет оптимизировать в принципе
>cc_dry2.exe 500000000

User time = 55 sec
Microseconds for one run through Dhrystone: 0.1
Dhrystones per Second: 9090909.0
DMIPS 5174.1
“Всего” в 84 раза быстрее интерпретатора, и вдвое медленнее оптимизированной версии.

Тест вычислений с плавающей точкой, например Scimark2 (он тоже старый и до сих пор используется, например в пакете performance

Результаты Scimark
Запуск только этого теста выглядит так
D:\VSProjects\Python36\python.exe pyperformance run -o py3z.json -b=scimark

Python version: 3.6.0 (64-bit) revision 41df79263a11
Report on Windows-7-6.1.7601-SP1
Number of logical CPUs: 4
Start date: 2017-01-19 03:03:35.583496
End date: 2017-01-19 03:07:00.042133
### scimark_fft ###
Median +- std dev: 863 ms +- 4 ms
### scimark_lu ###
Median +- std dev: 462 ms +- 10 ms
### scimark_monte_carlo ###
Median +- std dev: 247 ms +- 2 ms
### scimark_sor ###
Median +- std dev: 577 ms +- 6 ms
### scimark_sparse_mat_mult ###
Median +- std dev: 10.3 ms +- 0.1 ms

Результаты для одинакового с Питоном по количеству итераций теста на С
>gcc -mfpmath=sse -march=native -O2
FFT ms*50: 2.06 (N=1024)
SOR ms*10: 0.59 (100 x 100)
MonteCarlo: ms*1e5: 1.51
Sparse matmult ms: 0.79 (N=1000, nz=50000)
LU ms: 0.32 (M=100, N=100)

Расшифровка — Питоновский тест показывает время на одно выполнение теста, но которое может содержать разное количество одинаковых итераций, например преобразование Фурье считается 50 раз, что отражено множителем в С-результатах.

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

Отключение оптимизаций и SIMD на С дает в 3-4 раза более медленный результат
FFT ms*50: 8.80 (N=1024)
SOR ms*10: 0.66 (100 x 100)
MonteCarlo: ms*1e5: 4.04
Sparse matmult ms: 2.87 (N=1000, nz=50000)
LU ms: 1.11 (M=100, N=100)

Теперь о градации.

Если не брать в расчет чистые интерпретаторы вроде питона и старого PHP, все компиляторы и большинство JIT-машин укладываются в диапазон x2-x4, причем лучший JIT у Java и отстает в даже в наихудших случаях менее чем в 2 раза, а неправильными опциями компиляции С-программа расчета FFT, например замедляется впятеро.

С другой стороны, если посмотреть сюда, — в современном мире Javascript’а интерпретатор от вас гораздо ближе, чем вы думаете.

Способ измерения данного фактора приведен выше.

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

б) Влияние парадигмы программирования


На примере C++/D. Эти языки добавляют две основные парадигмы — ООП и шаблонное метапрограммирование. Дифирамбов им я петь не буду — посмотрим как это влияет на производительность.

Использование метапрограммирования. Шаблоны, макросы, частично дженерики (хотя объекты относятся к худшей карме). Шаблоны развернутся в код без потери в производительности или же даже с выгодой в скорости, поскольку функции inline’тся и исчезают потери на вызов. Всё, чем грозит их применение – это code bloating из-за генерации копий кода одних и тех же алгоритмов для разных типов данных.

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

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

Как измерить аспект — есть Тесты Степанова, показывающий ускорение до 2х раз при разворачивании вызовов и потери до 2% на виртуальные вызовы, но влияние code bloating оценить крайне трудно, см. ниже аспект памяти.

Оценка этого фактора скорости — от малозначимого до заметного.

в) Байт кодовые машины (BCVM)


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

Здесь существенна разница, будет ли промежуточный байт-код компилироваться JIT либо AOT, или же будет интерпретироваться. Также возможен смешанный вариант, когда BCVM проектировалась для другого языка и часть кода невозможно оттранслировать в Пи-код этой машины.

В любом случае, мы платим либо временем загрузки, либо памятью. Например, Java JIT обходится примерно в 100Мб памяти, что уже существенно, хотя результирующий код очень быстр и использует SIMD (проверено на днях в статье про ФФТ)

Как измерить — использовать тесты, зачастую достаточно посмотреть в Интернете, на что то вроде этого

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

Аспекты памяти


а) Стековое размещение


— не стоит ничего, обращение же к менеджеру динамической памяти уже часто тянет системный вызов. Вкупе со сборщиком мусора и фрагментацией памяти может составлять проблему для систем 24/7.

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

Измеряется тестами, само по себе стоит мало, но может тянуть за собой аспекты ниже.

б) Сборщик мусора (GC)


— непонятно, благословение для новичков или проклятие для “больших” — но поскольку с ним иногда приходится бороться, негативный фактор.

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

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

в) Динамическая загрузка


Когда мы запускаем новый класс — например открываем в программе новое окошко, происходит две вещи — нужно загрузить кусок связанного кода в случае машинного кода или фреймворка в случае BCVM- (смотрим про ООП и мать их всех родственников) и запустить JIT на загруженном коде.

Проверка для BCVM в реальности — можно провести простой тест — запускаем файловую нагрузку и усиленно лазим по интерфейсу — и теперь ваша программа работает со скоростью своппинга.
Полноценное тестирование затруднено, легко измерить только время загрузки и посмотреть на максимальные потенциальные аппетиты программы — размер VSZ memory для Linux и счетчик “Выделенная виртуальная память” в Windows. Немного поможет еще изучение статистики hard page faults.

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

г) Кэш процессора


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

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

Влияние — сложно оценить. В этой статье утверждается, что локализация данных в кэше дает ускорение в разы.

Аспекты реального мира


а) Системные вызовы


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

Измерение — тестирование на разных платформах. Оценка влияния — примерно как для выбора языка программирования, как малозначимая, кроме конкретных задач.

б) Насколько абстрактная производительность важна ?


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

в) Железо влияет


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

Неязыковые факторы


Алгоритмы решают всё. Например SQL проигрывает по языковым вычислительным характеристикам (это обычный интерпретатор), но из-за хорошего мат.аппарата и долгого времени доступа к данным, в целом выглядит хорошо. Тем не менее, в некоторых конкретных случаях слишком обобщенный подход SQL проигрывает прямой навигации типа M/Cache или NoSQL — решениям.

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

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

Аспект человеческого фактора


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

И что предлагается с этим делать?


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

Ответ второй – пишите на ассемблере, используйте только родные для системы инструменты и API.

Если же вам лень, слишком сложно, то у вас есть выбор – предложу следующий набор ступеней из программистского рая к грехопадению:

NULL. Использование Си. Чистый Си увеличит вашу программу только на размер run-time library (libc) в памяти, а современный оптимизатор не испортит исполняемый код.

На самом деле, не обязательно брать Си – годится любой компилируемый язык по вкусу – ADA, Modula, Oberon, даже Pascal/Delphi, желательно оптимизирующий

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

-2. Использование компилируемых объектных языков C++, D, Rust, Go. Что в этом плохого? С одной стороны, мода на объекты везде уже прошла, и многие трезвомыслящие разработчики критикуют объектный подход, что он не дает решающего выигрыша в разработке. С другой стороны – массивные наработанные обкатанные и удобные фреймворки. Проблема в том, что объекты в большей части фреймворка будут влинкованы, даже если они в вашей программе не используются. Упс, и ваш исполняемый файл перевалил за десяток мегабайт. Эти мегабайты занимают ваш диск, вашу память, и кэш процессора. Хотя накладные расходы на вызовы функций и измеряются парой процентов, но влияние занятости кэша процессора измерить сложно.

-1024. Интерпретируемые языки. PHP, CPython, отчасти Javascript. Благодаря им, сессия браузера перевалила за сотню мегабайт, а потеря на скорости вычислений в 100 раз – само собой нормальное дело.

-Pi. Виртуальные машины. Это языки с промежуточным байт кодом, базирующиеся на .NET платформе, либо на Java-платформе, ну и сюда же можно отнести и PyPy, и V8. Вы всегда с собой носите байт машину – она с вами на диске, она с вами в памяти. Хотя, если верить тестам, то кажется, что все почти нормально – проигрыш на вычислениях десятки процентов, ну максимум до 100% в худших случаях. Только тесты, как правило, не учитывают скорость загрузки самой виртуальной машины. И это память, память и еще раз память, десятки и сотни мегабайт.
Разработчики сами знают эту проблему и движутся в направлении компиляции в нативный код. Это ART вместо Dalvika для Android, и .NET Native от Microsoft.

P.S. Ну и для финального примера — у меня перед глазами 3 пользовательские программы, сходные по функциональности:

Одна написана на С++/Qt/Webkit
Другая на C# .NET 4.5
Третья на Python3/wx

Вот самая отзывчивая из них — на питоне, а самая медленная на дотнете.

Выводы — аспектов много, и учитывать только один — бесполезно.
Поделиться с друзьями
-->

Комментарии (30)


  1. zenkz
    17.04.2017 21:00
    +3

    Тема очень интересная. Конечно, как .Net разработчик, я не сторонник версии «назад к истокам» и написанию программ на ассемблере или чистом C(++).
    С другой стороны я тоже хотел написать подобную статью, но в несколько в другом аспекте. Проблема в том, что сейчас программы сходные по функционалу весят в десятки и сотни раз больше, чем их аналоги 10 лет назад. Взять к примеру Скайп — размер дистрибутива вырос до нескольких сотен мегабайт, хотя функционала не прибавил. То же самое и с большинством программного обеспечения и даже с веб-сайтами.
    И в данном случае проблема даже не в компиляторах и в неоптимизированном коде, а в том, что в погоне за скоростью разработки подключаются фреймворки и библиотеки там, где они не нужны. Нужна простая таблица на веб-странице — подключаем в лучшем случае jqGrid или более современный аналог, в худшем — целый пакет компонентов от Telerik, Infragistics или DevExpress. И неважно что из всей их мощи вам понадобится только сортировка и постраничное отображение.

    Недавно был опыт — нужно было написать веб-интерфейс для микроконтроллера (ESP8266). JQuery туда не зальёшь т.к. нет места, а доступа в интернет может и не быть. Пришлось писать на чистом JS. В результате получилась мини-библиотека весом несколько килобайт с основным функционалом JQuery (как выбор элемента по ID, навешивание классов и изменение свойств и т.д.)


    1. Lorys
      17.04.2017 21:43

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

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

      Но с сайтами пол беды — многие работают более-менее нормально без JS, можно найти приемлемые сайты не заваленые кучей JS, рекламы и счётчиков. Но браузеры…

      На моём стареньком ноутбуке самая большая проблема — это сёрфинг в интернете. Я могу запустить кучу программ не являющихся браузерами в том или ином виде (сами браузеры, программы на Electron и т.д), и всё будет ок, но стоит мне запустить FireFox или Chrome — ноут тихонько умирает. При этом, скачав FireFox 37 (и ранее), почувствовал как была прекрасна жизнь несколько лет назад (всё летает и ничего не тормозит), но отвалились сайты сделанные на флексбоксах и тд…


    1. VioletGiraffe
      17.04.2017 22:40

      JS на микроконтроллере — это как? Где интерпретатор?
      Как называется эта технология?


      1. zenkz
        17.04.2017 23:37
        +1

        JS в браузере у клиента. Но хранится на микроконтроллере. От того и все ограничения.


    1. qRoC
      18.04.2017 17:04
      +2

      Проблема в том что сегодня Вам понадобился функционал по выбору по ID, завтра простенькая анимация, через неделю Вы вспомнили про кроссбраузерность, а через год Вы ошибочно гордитесь что написали свой клон jQuery.
      Хотя ещё в первый день Вам никто не мешал взять только то что нужно было и пройтись, к примеру, Google Closure.


  1. apro
    17.04.2017 21:18

    Недавно был опыт — нужно было написать веб-интерфейс для микроконтроллера (ESP8266). JQuery туда не >зальёшь т.к. нет места, а доступа в интернет может и не быть. Пришлось писать на чистом JS. В результате >получилась мини-библиотека весом несколько килобайт с основным функционалом JQuery (как выбор элемента по >ID, навешивание классов и изменение свойств и т.д.)

    Насктолько не было место, что 82 килобайта не влезло (82K Jun 13 2016 static/jquery-2.0.3.min.js)?
    А как туда TCP/IP влез, или он и занял все свободное метсто?


    1. zenkz
      17.04.2017 22:13
      +5

      В моём случае — 512 килобайт.
      Да, 82 килобайта бы влезло, но я предпочитаю использовать это место более эффективно. К примеру CSS стили прикрутить, иконки положить, больше функционала реализовать.

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


      1. HaMI
        17.04.2017 23:27
        +7

        >Без обид, но ваш комментарий — типичная логика современного разработчика
        Без обид, но ваш комментарий – типичная логика «несовременных» разработчиков-одиночек любяших все держать под контроллем(мнимым). По запросу «jquery minimal» вы могли найти вагон и маленькую тележку библиотек минимального размера, вроде Zepto(~10kb, но я думаю можно вложится в 2kb или меньше, если собрать только, то что нужно). Но вы сознательно сделали все на коленке и к эффективности это не имеет никакого отношения. Если вы ставили себе целью – разобраться, то ок – но не рассказывайте про эффективность

        Есть еще второй вариант – вы сделали обзор существующих решений и пришли к выводу что они не подходят, потом разработали свою уникальную библиотеку. Тогда не томите – github ждет


        1. zenkz
          18.04.2017 00:36

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

          Я не сторонник «велосипедов» (т.к. библиотеки чаще всего не содержат критических ошибок, а велосипеды — вполне могут), но и не сторонник добавления библиотек на каждый чих.


    1. Nagisa
      20.04.2017 03:17

      так, для понимания, к примеру у меня стек tcp/ip весит менее 16кБ в чистом виде и 24кБ с DHCP/NTP client-server/SNMP/ICMP client-server. простой web сервер — ну еще 8кБ. чистый си для AVR-а.


      1. apro
        20.04.2017 16:02
        +1

        так, для понимания, к примеру у меня стек tcp/ip весит менее 16кБ в чистом виде и 24кБ с DHCP/NTP client-server/SNMP/ICMP client-server. простой web сервер — ну еще 8кБ. чистый си для AVR-а.

        Без уточнения что выбросили и чем пожертвовали, это бесполезно "для понимания".


        Например, насколько я знаю, uIP (одна из известных микро реализаций TCP/IP) не умеет
        сборку фрагментированных пакетов.


  1. berez
    17.04.2017 21:27
    +10

    Мешанина какая-то.
    Ну да, драйстоуны, ветстоуны, компиляторы, интерпретаторы, байткод, кэш, code bloat — все это прекрасные слова, но зачем вы все это свалили в одну кучу и приправили жиденькими, бесполезными рекомендациями?

    Рекомендации должны быть предметными, а не «вообще».

    — Важна производительность именно вычислительная? Тогда — компилируемые языки, многопоточность, распаралеливание, использование GPU (OpenCL, CUDA), распределенные вычисления. У вас из всего этого — только мутноватые рассуждения о производительности и издевательские рекомендации писать на ассемблере. Издевательские — потому что современные компиляторы генерируют код весьма высокого качества, а попытки оптимизировать его вручную обычно приводят к тому, что «оптимизированная» программа работает медленнее оригинала. Кроме того, писать на ассемблере под тот же ARM — занятие для истинных гурманов.

    — Важен отклик пользовательского интерфейса программы? Тогда — правильное проектирование, обработка длительных операций в отдельном потоке, и пофиг на язык программирования. Время комфортного отклика на действия пользователя — ЕМНИП, что-то около 250 миллисекунд. На такую производительность вполне способны даже весьма медленные языки программирования.

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


    1. Siemargl
      17.04.2017 23:02
      -5

      Ну и зачем писать бесполезные общие рекомендации, которых полно в Интернете вроде «как написать супербыструю программу на Бейсике»?! Я описал причины, а конкретные применения каждый пусть применяет к себе сам. Кроме того, см 1й абзац.

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


      1. berez
        18.04.2017 14:57
        +1

        Я описал причины,

        Да ничего вы толком не описали. Так, общие рассуждения и минимум конкретики.
        Самое обидное — вы оставили за бортом самый главный вопрос: с чем боремся-то? С жЫром или с тормозами?

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

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

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


    1. Alexsandr_SE
      19.04.2017 12:25

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


  1. VioletGiraffe
    17.04.2017 21:45

    Промахнулся, это ответ на комментарий zenkz.

    Уверен, что объём Скайпа, как и всех других приложений ненормального размера — не от кода. Это какие-то ресурсы. Кода может быть от силы 40 МБ, и то из них 20 будут всякие таблицы для работы с Юникодом (то есть тоже не совсем код).


    1. sshikov
      17.04.2017 22:24

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


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


      Ну и чего стоит название данного поста? Да лучше бы эта программа была еще толще (больше места занимала на диске), но зато простейшие текстовые меню открывала бы сразу, а не через пару минут.


    1. zenkz
      17.04.2017 22:38
      +1

      Скайп — это просто пример.
      Не поленился и посмотрел что из себя представляет папка со скайпом:
      80 Мб библиотек и исполняемых файлов.
      Топ 3:
      SkypeSkylib.dll 28 Мб
      Skype.exe 26 Мб
      SkypeResources 15 Мб

      В памяти скайп сейчас занимает скромные 28 Мб, но к нему идут ещё 2 процесса Skype Browser Host (48 + 32 Мб) Итого 100 Мб в памяти. Но это не большая проблема. Проблема в том, что он периодически грузит диск под 100% на некоторое время.
      Также скайп ненавистен тем, что обновляется в самый неподходящий момент и вообще считает пользователя рабом. (Типичные ошибки современных приложений — к примеру заставлять обновляться на каждую следующую версию).

      Но это ещё цветочки, т.к. те же браузеры (у меня сейчас открыто их 2 Firefox и Chrome сжирают около 2х гигов совместными усилиями — и это при 20-30 открытых вкладках)


      1. VioletGiraffe
        17.04.2017 23:26

        Думаю, десятки мегабайт в этих бинарниках — тоже ресурсы.


      1. SerafimArts
        18.04.2017 03:23

        А если учитывать то, что:
        1) Скайп хранит вообще все данные в совершенно открытом виде в sqlite файлике без какой-либо защиты
        2) Имеет тенденцию после пары любых "левых" жалоб блокировать аккаунт навсегда, без возможности восстановления в автоматическом режиме без участия операторов.
        3) И, не знаю как, но его можно взломать, пройдя двухфакторную аутентификацию без отправки смс уведомлений (давеча сам лично столкнулся с "левыми" ссылками на гугл, рассылаемыми от всех контактов подряд).


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


  1. sbnur
    18.04.2017 10:00
    +1

    Ваше замечание про замедление скорости реакции на щелкание мышкой мне очень понравилось.
    Я давно заметил эту закономерность при переходе от 8086 -> 80286 -> 80386 -> и тд
    Через месяц работы после смены системного блока я по своей реакции начинаю обгонять реакцию компьютера


  1. Lailore
    18.04.2017 10:17
    +1

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


    1. Siemargl
      18.04.2017 10:23

      Во-первых, никто не предлагает жертвовать красотой

      Во-вторых, красота понятие относительное

      В-третьих, ваша точка зрения будет отличаться в случаях если вы получаете ренту за обслуживание 10 серверов вместо одного, либо вы платите за эти 10 серверов вместо одного =)


      1. Lailore
        18.04.2017 10:32
        +1

        Если у меня будет проект, который допустим грузит 10 машин на 100% на C#, то количество машин перестанет быть такой проблемой.


        1. Siemargl
          18.04.2017 11:24
          -1

          Нагрузка бэкэнда считается по пику.

          А полная нагрузка Проблемой будет в любом случае.

          Кстати, про 10% производительности С# в бэкэнде почти точно угадано — смотрим тут результат aspnetcore-mvc-ef
          И красотой жертвовать не надо — ef это же скорее всего Enterprise Framework — все красиво, стандартно, канонически и искаропки.

          Или это Вы сразу себе оправдание для шефа придумываете? =)


          1. Lailore
            18.04.2017 11:42
            +5

            aspnetcore работает хуже nodejs? Серьезно? Я очень слабо в это верю

            И как я понял, тут целый фреймворк сравнивается просто со стримом?


            1. SirEdvin
              18.04.2017 12:01
              -3

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


              1. Razaz
                19.04.2017 22:30

                На самом деле надо отделять мух от котлет. Core смоделирован по подобию ноды — вебсервер(на выбор) + middleware + что-то там за ним(MVC, Nancy).
                1. Есть минимум — Kestrel + Middleware. Тут node.js сильно отстает — это хорошо видно на plaintext бэнче: 1800k vs 467k.
                2. Есть Kestrel + Middleware + MVC. Логично сравнивать с express — 653k vs 213k.
                Это были только чистые сервер + фреймворк.

                Попа начинается, когда в дело вступает зоопарк сериализаторов на .Net, из которого взяли популярной, но не самый быстрый и слегка кривенький драйвер для Npgsql. То есть к самому .Net это уже прямого отношения не имеет. Если сравнить результаты тестов, то будет видно, что при работе с базой — их производительность практически идентична и вопрос скорее всего к конкретному Data Provider.

                Плюс все эти тесты проводятся на Linux. На WinServer и SqlServer было бы интересно взглянуть в тех же конфигурациях. Ну и все развивается :) Сейчас Kestrel c libuv слезет и огого что будет :D


          1. Razaz
            19.04.2017 21:31

            А вы уберите EF. Он не обязателен. Причем там Npgsql, который не сказать что бы мега оптимален на Core и под Linux. Там есть косяки типа:

            // postgres has problems with deadlocks when these aren't sorted
            Array.Sort<World>(results, (a, b) => a.Id.CompareTo(b.Id));
            

            Так же сериализатор надо бы на Jil, а не Newtonsoft.Json -> So I Heard Jil Is the New JSON Serializer Champion.


  1. Alexey2005
    19.04.2017 11:53

    Просто фреймворк должен соответствовать решаемой задаче. Если вы делаете игру уровня Тетриса на Unity, то вполне заслуживаете проклятия, потому как для такой игры даже SDL многовато будет.
    Если у вас сайт содержит одну только статику, а вы додумались использовать ангулярщину для эмуляции перехода по ссылкам, пользователь может и должен пинать вас ногами.
    Почему так получается? Да просто большинство кодеров плотно подсело на единственный любимый фреймворк, который используется для абсолютно любого проекта — ведь в остальном же ещё разбирать надо, а тут можно начать кодить сходу. Ну да, гвозди забиваем электронным микроскопом. Зато микроскоп уже под рукой, а за молотком надо в магазин бежать.