• performance latency Я всё размышляю, что же пошло не так, отчего софт всё тормозит, хотя производительность железа всё растёт. Кажется один из факторов — культурный. В информационном поле почти отсутствует мысль о важности отзывчивости и легковесности. Вот сколько я встречал списков сравнения best N apps for task X — не припомню, чтобы хотя бы в одном из них был замер использованного процессорного времени и памяти на выполнение аналогичных действий, примерно как я делал в #2890539 . Вот в качестве пруфа можно погуглить "image viewers performance comparison" — очень мало ожидаемых результатов, всего ~3 в первой десятке! А для запроса "bittorrent clients performance comparison" в первой десятке только одна релевантная ссылка аж от 2010 год (ну и для справедливости ещё одна работа со сравнением скорости скачивания двух клиентов).

    В идеальном мире в сравнительных обзорах были бы сравнения производительности с замерами, что давало бы разработчикам соревновательный стимул к оптимизации. Да, premature optimization — зло, но если ты вообще не прогонял свою программу через профайлер, то ты редиска.
    ♡ recommended by @OCTAGRAM

Replies (58)

  • @Self-Perfection, Получит ли оптимизированное ПО конкурентное преимущество в современном мире?
  • @Self-Perfection, Всё потому же, почему есть такое php.net
  • @nibb13, два чая за этот столик.

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

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

    поэтому затраты на оптимизацию и тестирование — просто непозволительны. надо фичи релизить, блеать, на рынок. потому что если ты сделал это на пару месяцев позже конкуретна, то тебя на рынке просто нет. а ещё через 4 месяца эта тема и вовсе будет забыта.
  • @nibb13, С одной стороны да, получит. Из наиболее характерного — много раз встречал в обсуждениях мс офис вс опен офис аргумент: "у меня excel файлы мегабайтные, слишком медленно с ними опен офис работает"

    С другой стороны, о чем я и пишу, нет в культуре внимания к производительности. Пользователи привыкли, что всё примерно одинаково тормозит, да и не умеют обращать внимание на скорость. Замеры прожорливости приложений в обзорах сделали бы этот параметр более весомым для пользователей при выборе, больше влияющим на конкурентное преимущество.
  • @Self-Perfection, Довольно странно сравнивать бесплатное и платное ПО. Если в продукт вбахивают бабло — оно по умолчанию должно быть лучше, иначе неконкурентоспособно, тогда как у продукта, держащегося на энтузиазме — совсем другие цели.
  • @gothicsquash, Мне не интересны столь быстро устаревающие области. Приложением для просмотра картинок или записывания своих расходов человек будет пользоваться годами и что, в этих приложениях уделяют больше внимания оптимизации?

    Или вот если Н пишет freeware для души и спешить некуда — больше оптимизирует разве?
  • @ambi, Делает ли это замечание пример получения конкурентного преимущества мс офисом над опен офисом от скорости некорректным?
  • @ambi, Отчасти да, но слипы явно не основная причина. Хотя мысль выдавать компиляторам warningпри обнаружении sleep без комментария рядом мне кажется перспективной, избавление от слипов совсем проблему не решит.
  • @Self-Perfection, И да, и нет. Если мы хотим, чтобы скорость OpenOffice была на уровне офиса от МС — давайте вкладывать в него деньги. За редким исключением бесплатный аналог всегда хуже.
  • @gothicsquash, Сколько лет уже миллиарды людей продолжают пользоваться тормозящими приложениями в Андроиде, приложениями из базовой поставки, которые одинаковые на миллиардах устройств
  • @kunsun, сколько лет их становится таких всё больше, и сколько раз свежайшие флагманы за год превращались в говно инвалида?

    это лишь подтверждает тезис в /3. где деньги, Карл? нет денег — нет суппорта. в оптимизации денег нет почти никогда. а в новых фичах деньги есть почти всегда. если старое тормозное предложение не обновляется новыми свистоперделками, то на него просто кладут хер.
  • @Self-Perfection, Приложением для просмотра картинок меняют модель потребления с приобретения lifetime лицензии на подписку. постоянно какая-то херота обновляется в бэкграунде, и списывается пятёрик долларов в месяц.
    бесплатная прога? заебут рекламой и внутриприложенческими покупками.
    опенсорсная прога? либо вечно догоняющий инвалид, либо последний апдейт в 2013 году.

    записывания своих расходовесли это что-то сильнее таблиц в экселе, типа sanuel family pro, то точно такая же залупа. апдейты, новая хуйня в виде приложения в телефон. версия с синком или без синка, свистоперделки, реклама, или заложеный хуй.

    чудес не бывает.
  • @gothicsquash, Я чего этот вопрос задаю?.. Пишу сейчас по собственной инициативе довольно сложное ПО, которое потом собираюсь продавать конечному пользователю. И "ползаю по нему с линейкой" с точностью до горстки бит ещё с самой ранней альфы. Потому как писать код, который бездумно жрёт ресурсы, я попросту не могу: противно на подсознательном уровне. Заканчивается 2017-й, а на моём основном "продакшн сервере" до сих пор 32 метра оперативки. И я до сих пор считаю, что этого достаточно. Ну, 64 сделали бы меня безгранично счастливым, конечно... :)
    Так вот интересно, насколько такой подход в принципе жизнеспособен сегодня. Не сожрут ли конкуренты с безлимитными индусами, пока я буду тратить лишние пару часов на технику более эффективной укладки bitmapdata в памяти?
  • @Self-Perfection, И с точки зрения пользователя этот вопрос тоже интересен. Если, вдруг, к современному усреднённому юзеру попадает ПО, которое ощутимо фичастее существующих аналогов (несомненный плюс), но при этом ещё и не тормозит по глупости, не выжирает память тоннами, где в ней нет необходимости, сохраняет проекты любого размера мгновенно и хранит историю undo вечно, до самого первого действия, рядом с проектом — заметит ли это юзер? Сконвертируется ли это в рекламу "сарафанного радио"?

    Как я уже сказал в /13 — по другому я не умею. Вот и поэкспериментируем...
  • @Self-Perfection, Я это увязываю с увлечением сборкой мусора. Понакупят разработчики ни-фига-себе-ноутбуки с 16Гб, а программы их работать будут хорошо, если на 1Гб офисных компах в бюджетных организациях. А ещё с увлечением HTML5 вместо нативных средств разработки. А HTML5 тянет паровозом и сборку мусора, и слоистые буферы для оптимизации не заточенной под железо CSS вёрстки.

    Мне кажется, нужно решить проблему с кроссплатформенной разработкой без сборки мусора, и тогда пробьётся свет в конце тоннеля.
  • @Self-Perfection, научитесь сначала писать качественный и незабагованный напрочь софт, а уж потом о скорости думайте. Задолбали, как обсуждать какой плиткой пол в деревенском туалете покрывать, в то время как космические корабли бороздят просторы большого театра.
  • @OCTAGRAM, ну rust все гнобят, а это единственный язык (не считая сдохших mlton), которые сделали шаги в этом направлении.

    ну и врятли, большинство софта это плюсы и они прекрасно тормозят и без сборки мусора
  • @qnikst, Уоу, уоу, уоу, как это единственный? А как же программирование на интерфейсах в Делфи (см. mORMot)? Objective-C 2.0 ARC? В Swift, как я понял, та же история. Perl и Python. Да и на Аде с C++ из RAII вырастает ARC замечательно. Потом ещё Cyclone был. А Rust уже после прочих пришёл. Какие таки шаги его создатели могли сделать?
  • @nibb13, Мне бы понравился дешевый андроид телефон с не тормозящей на пустом месте прошивкой. И сарафанное радио бы точно было у такого продукта
  • @OCTAGRAM, владение, его передача, контроль времени жизни на уровне типов. мы же в треде про скорость и память говорим. Ну ещё была пара языков и статей про линейные и афинные типы, но ничего юзабельней от пока так и не сделали.
  • @OCTAGRAM, в отношении корректности ада, кстати, очень хороший язык, как для своего времени, так и в наши дни, последнее правда не факт, что заслуга ады, а не проблема современных языков.
  • @qnikst, Как человеку, который лет 16, то есть, практически всегда пишет в стиле либо уникальных ссылок, либо со счётчиком ссылок, мне удивительно слышать, что, оказывается, я мог делать это только на Rust.

    линейные и афинные типыТо есть, как адский limited и запрещённый переносом в private копирующий конструктор в C++?

    контроль времени жизни на уровне типовRAII и/или ARC разве не об этом?
  • @qnikst, большинство софта это плюсы
    То большинство софта, которое я лично наблюдаю — это браузерный суррогат
  • @OCTAGRAM, RAII это костыль позволяющий контроль за ресурсами в языке, который не умеет выражать необходимые инварианты в типах. В некоторых языках (swift) arc используется ровно для того же.

    предложение про limited я не смог распарсить, переформулируй пожалуйста.

    То что можно сделать с помощью монад в Haskell можно сделать при помощи, внимательности, боли и страдания в других ЯП, я знаю. Тут тоже самое. Язык не помогает писать качественно (в данном случае ещё и чтобы выходила эффективная программа), первый язык похожий на индустриальных, который с начала 80х сделал шаги в этом направлении это rust.
  • @nibb13, думаю, сожрут.
    давай так. сколько ты уже времени потратил на разработку? чисто так, в трудочасах. помножь на стоимость твоего часа времени. и прикинь, что надо сделать, чтобы оно окупилось вот прям сейчас.

    а заодно представь, сколько нынче стоят 32 метра оперативки. ну так, навскидку.

    не надо рассматривать это как олимпиаду по программированию. надо рассматривать это как бизнес. а бизнес измеряется немного иначе.
  • @kunsun, это невозможно. обсуждали уже миллион раз.
    не соблюдено главное условие: "железо + операционка + маркет — свои собственные".
    в итоге с ним происходит то же, что и со всеми подобными: операционка не обновляется практически никогда, приложения из маркета обновляются каждый день. всё это в связке никем не тестируется, накапливаются проблемы, и телефон превращается в говно.
    гнусмасы — лучшие телефоны на момент релиза, потому что этот релиз тестировался и чинили баги. а через год после релиза они просто ебаные инвалиды. как и все остальные, не соблюдающие главное условие.
  • @qnikst, RAII это костыльНе могу это понять. RAII даёт прямой доступ именно к тому, к чему надо. Чего ещё можно желать сверх этого?

    предложение про limited я не смог распарситьЗапретили копирование — и вот он, линейный тип, разве не так?
  • @gothicsquash, В переводе с русского на русский: надо рассматривать это как звериный оскал капитализма.
  • @gothicsquash, учитывая, что не каждая задача по количеству данных (упакованных), которые встречаются влезет в 32 метра, причем даже с учётом потоковой обработки. А для данных такого размера даже весьма неэффективный алгоритм и Гц не помешают (ну если у тебя там не микротранзации, счет на микросекунды и все дела)
  • @OCTAGRAM, линейный тип это запретили использование переменной отличное от 1 раза. Если тип поддерживает копирование — копируй данные, кто мешает то, и будут у тебя 2 несвязанных инстанса используй как надо. Ты почитай статейки, там интересно.

    RAII это соглашение (?) о том как писать программы, чтобы они были более менее адекватно работающие. RAII был нужен, т.к. язык не помогает и без него получалось плохо писать. Вещь прилепленная сбоку для того, чтобы ходить прямее, а не падать называется костыль.
  • @qnikst, линейный тип это запретили использование переменной отличное от 1 разаА если больше 1 раза, то что? И что значит, использование? Вызов в режиме in out — это использование?

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

    соглашение (?) о том как писать программыКто с кем соглашается? Оно реализуется трансляторами. Авторы библиотек пишут, как управлять ресурсами при манипуляции типами, транслятор это воплощает. Авторы библиотеки сами с собой соглашаются?
  • @qnikst, Не считаю, что задачи устранения багов и оптимизации производительности нужно решать последовательно, т.к. багов слишком много, до производительности так можно не добраться никогда.

    Но подумать, над проблемой забагованности в ключе мысли топик старта интересно. Запрос на безглючность тоже кажется недостаточно выражен. Может быть в идеальном мире также было бы правилом хорошего тона иметь публичный багтрекер даже для проприетарщины, и в обзорах софта также указывались бы метрики по багтрекерам, типа скорости появления новых багрепортов и закрытия самых залайканных багов? Интересно, но более сомнительно, чем для замеров производительности, всё-таки массовый пользователь в репортинг багов не умеет.
  • @Self-Perfection, В обзорах софта можно было бы в правильном ключе подавать язык реализации, в частности, насчёт безопасности и сборки мусора. Это попроще, чем трекеры.С трекерами всё очень субъективно. Неклиенты любят чего-нибудь попросить более активно, чем клиенты.
  • @OCTAGRAM, давай ты что-ли хотя в Википедию по теме этой почитаешь (если там есть статья) мне немного лень вдаваться в объяснения в настолько воинственном окружении
  • @gothicsquash, это возможно на компьютерах но не возможно на мобилках, почему?
    что мешает ли си цину производящему дешевые ведра поставить туда какой-нибудь цианоген который по 3 раза в день сам обновляется
  • @qnikst, Да читал я не один раз. Запомнился пример DSL для обработки XML, где транслятор проверяет порядок поедания значений, и при удовлетворении требований порядка алгоритм можно транслировать в потоковую форму. Какая-то экзотика по типу GLR парсеров, я так понял, а в остальном всё сводится к возможности запретить копирование.

    Если я реализую тип сетевого сокета и указал, какой вызов OS делать при уничтожении, то где в данном случае костыльность RAII? Тут ничего же ни прибавить, ни отнять.

    И к /0 : практика COM времён Windows NT Terminal Server показывает, что счётчика ссылок и RAII хватало писать быстрые приложения. А Джава выедала сразу 20Мб, иначе не могла работать. Emacs расшифровывали как Eight Megabytes And Constantly Swapping. На недостаток экзотики типа GLR в языках общего назначения подобных жалоб вроде не поступало.
  • @OCTAGRAM, я не знаю как я читал, если про линейные и аффинные типы каждое утверждение неверно. мне честно лень начинать это обсуждение с выстраивания общего словаря. Когда я говорю типы, а ты пишешь про конструкторы и деструкторы, т.е. мир значений, то я честно не знаю как вообще разговаривать. Про какие манипуляции над типами ты говоришь? ни один из перечисленных языков не умеет операции над типами, а некоторые и типов то не имеют, они умеют операции над значениями. Вот чтобы нормально общаться нужно выстроить весь этот словарь, чтобы лицо собеседника не покрывалось facepalmами от удивления
  • @Self-Perfection, корректность всегда важнее оптимизации, в крайнем случае когда скорость является частью корректности, то так же важна. Со скоростью тут важно является ли определенная часть продукта bottleneck-ом и насколько дает толк оптимизация, и тут для разного класса задач существуют разные ответы. Будет ли реакция на клик 1мс или 10мс тебе большой разницы не будет. Если ты сделаешь тот же продукт, который будет просматривать картинку в 3Мб вместо 30 — тоже большой разницы не даст, но есть вероятность, что в первом случае ты можешь его делать в 3 раза дольше. А развитие компилятора или интепретатора за это же время + развитие железа сведет толк на нет.
    К сожалению, сейчас очень часто делают предварительную пессимизацию, и это плохо и все тормозит действительно больше, чем надо, но мне кажется это меньшее зло, чем если эти же криворукие программисты (большинство программистов, я не исключение, криворукие) начнут все яро оптимизировать и плодить очередные баги.
  • @OCTAGRAM, И что значит, использование? Вызов в режиме in out — это использование?
    Here Rust defines a "use" to be pass-by-value. Pass-by-reference isn't considered a use.
    Ага. Тем, кто хочет такое реализовать, приходится придумывать, как напялить линейные™ типы на реальную жизнь. И после того, как напялили, в том, что получилось, угадываются именно эти привычные вещи из реальной жизни, а не линейные™ типы. Значит, как я и думал, вызов в режиме in out — это не использование.

    fn step1() -> Step1Token; // malloc, fopen, glCreateContext, connect
    fn step2(Step1Token) -> Step2Token; // write, read, mutate, draw, send
    fn step3(Step2Token); // free, close, destroy

    Что я тут вижу? Во-первых, у нх тм свя атмсфр. Во-вторых, мягко скажем, иначе записанные контракты. Ну как-то контракт проще записать, мне кажется.

    Обязательность быть использованным как минимум один раз свелась к вызову деструктора, то есть, как я и думал, к RAII. Ну разве что в языке Ада limited, не упакованные в холдеры, имеют блочные (взаимовложенные) области действия, а в Rust — перекрывающиеся. А перекрываться они могут только в динамической памяти, то есть, как если адский limited всегда дополнительно класть в холдер. Пустоту/полноту холдера до и после можно указывать в контрактах.

    Может быть, что-то сильно меняет то обстоятельство, что вместо единого деструктора уничтожение значения может произойти несколькими способами, все функции потенциально являются деструкторами. Хочешь — так уничтожь, хочешь — этак. В один деструктор добавил вызов OS, в другой — забыл. Это из-за этого сыр-бор?
  • @OCTAGRAM, вместо ответа я оставляю ссылку на blurb paradox
  • @qnikst, И как-то по-простому, я так понимаю, парадокс не разрешить, потому что пишут всё статьи да статьи, а не реальный код

    google.ru
    google.ru
  • @OCTAGRAM, github.com линейные + афинные

    github.com афинные, которые промоутятся компилятором до линейных
  • @qnikst, В произвольно открываемых файлах я не вижу чего-то, что указало бы на качественное отличие от RAII
  • @OCTAGRAM, учитывая

    ни один из перечисленных языков не умеет операции над типами, а некоторые и типов то не имеют, они умеют операции над значениями.
    это не удивительно. Да счетчики ссылок и RAII и другие костыли конечно позволяют писать софт, и на алголе и фортране норм софт писали, где не было и того, что в плюсах в аде. Это же не значит, что этого достаточно. Впрочем большинство современных языков от алгола-68 не сильно отличаются, и можно все начинать сравнивать с ним.
  • @OCTAGRAM, можно писать так можно, было бы странно если нельзя, с 72-года примерно можно. Я говорю про то, в каких языках есть существенные подвижки начиная с тех пор.
  • @qnikst, Что есть «операции над типами»?
  • @OCTAGRAM, (упрощенно) операции над типами это метод агрументами которого являются типы, а результатом является тип.
  • @qnikst, То есть, в C++ сделали RAII и через него unique_ptr и пр., но не контракты; слов «линейный тип» не было, значит, подвижек нет, так?
    В языке Ада сделали limited, RAII и контракты, а через них можно тоже чего-то выразить, но слов «линейный тип» нет, значит, подвижек нет, так?
    В Rust сделали limited, RAII, и не забыли сказать, что это «линейные типы». Нужные слова есть, значит, подвижки есть, так?
  • @qnikst, В рантайме это операции над дескрипторами типов, во время компиляции — generics или templates, так?
  • @OCTAGRAM, RAII можно иметь в любом языке, к языку это не имеет никакого отношения, unique_ptr это часть библиотеки, к языку не имеет никакого отношения, RAII никак не выражен на уровне типов и не позволяет компилятору выводить свойства. limited это хорошо, но ни к линейным типам не имеет никакого отношения, я не знаю почему ты в очередной раз связываешь их. Линейные типы это не запрет на копирование. Контракты это хорошо, но это совершенно другое направление.

    Ещё раз limited+RAII это не линейные типы.
  • @OCTAGRAM, В рантайме это ничего, во время компиляции это частично покрывается templates в CPP, generics (если тот который в mainstream типа java и т.п. то это не то).
  • @OCTAGRAM, псевдокод

    void foo(linear int a, linear int b) {
    int c = a + b;// ok (1)
    // int d = a+ a; type error
    int d = a + 1; // type error "a" is used more than once
    }

    не знаю как RAII и limited позволяют это получить
  • @OCTAGRAM, заметь я не говорю, что это невозможно в cpp или ada, и что без этого не написать хороший софт. Просто тут языки не помогают, причем для того. чтобы сделать все эффективно ещё появляется куча соглашений, специальных аллокаторов, чтобы работало хорошо и вообще хороший рост сложности, без поддержки компилятором.
  • @qnikst, RAII гарантирует, что значение в конечном итоге куда-то зайдёт, и это будет деструктор. limited запретит копирование. Флаг «пустоты» и limited можно навесить в generic package, в контрактах написать, что на вход "+" поступают пустые значения, на выход — заполненные. Если компилятор увидит по контрактам, что флаг пустоты не совпадёт в рантайме, он пожалуется. Я так понял, надо чтоб даже флага пустоты не было?

    Где это может быть нужно? А если вложенное значение — указатель, то флаг пустоты естественно заменяется null, а в непустом значении должен быть not null указатель, и под флаг пустоты даже дополнительное место не тратится.
  • @OCTAGRAM, если RAII гарантирует, что значение куда-то зайдет, то я что-то о нём не знаю (это вполне возможно, я не умею в плюсы на нормальном уровне).
    Дальше, линейные типы это дополнительная информация о типе значения, которую знает компилятор и может проверять инварианты во время компиляции, в рантайме никаких проверок нету. Любой тип int, Object, Int{>5} может быть сделан линейным, если он линейный, то ты обязан его использовать (что такое использовать определяется операционной семантикой языка), так же это обозначает, что ты или должен вернуть другое значениие этого же типа, или его потребить, что обычно (но не обязательно) обозначает освободить ресурс. Т.е. ты гарантировано никогда не забудешь delete, или закоммитить или отменить транзакцию, или заполнить кусок памяти, как бы ты эти данные не передавал между тредами и компонентами программы. Так же это полностью убирает ошибки use after free (правильное использование RAII тоже убирает use after free, но можно написать и неправильно и его словить). Так же это позволяет писать immutable алгоритмы о которых проще думать, а компилятору превращать из в mutable, т.к. есть необходимые гарантии о том что нету data race, конкурентного доступа и т.п.. В итоге писать алгоритмы из этого класса становится проще. Т.е. линейные типы: убирают use after free, resource leak, позволяют early release, позволяют удобнее писать примитивы для конкурентности и делать более сложные инварианты и оптимизации. Афинные типы это ослабление линейности, и позволяет не потреблять ресурс — о них гораздо проще думать программисту, но меньше гарантии. У раста внутри линейные типы (если смотреть MIR), а наружу афинные.

    В чем заслуга раста по сравнению с другими языками, несмотря на то, что во всех языках есть возможность писать безопасно и даже в языках с GC можно хранить данные вне GC-heap и иметь ARC (чем и пользуются), так вот, у rust появилась проверка этой безопасности на уровне компилятора, при этом без теорем пруверов и всяких доказывалок типа SPARK. Эта идея не новая, но это первый язык, который вынес её на новый уровень.
  • @qnikst, Я так понимаю, что гипотетически компилятор может пытаться заставить разработчика вручную заводить линейное значение в какую-то из функций, которая его съест. Но я пока не вижу смысла этого делать по сравнению с тем, чтобы по-тихому заводить значения в деструктор, где в единственном месте программы написано, как уничтожить значение.

    проверять инварианты во время компиляцииВроде бы, контракты — об этом же. Инвариант на слух звучит как нечто вроде адского procedure Modify (X : in out Item_Type) with Post => F (X) = F (X'Old); … где F — функция инварианта.

    use after free, но можно написать и неправильно и его словитьС готовыми контейнерами это сильно вряд ли.

    immutable алгоритмы о которых проще думать, а компилятору превращать из в mutableВот это, пожалуй, самое интересное. То есть, как в GLR, выворачивание наизнанку. Или как при трансформации алгоритма, записанного для DOM, в алгоритм, записанный для SAX. Время снаружи абстракции течёт не так, как внутри. Да, тут есть потенциал для оптимизации. Хотя, с другой стороны, смотреть на такие трансформации надо внимательно. Во времена Ада 83 не стали делать отдельно protected в расчёте, что умные компиляторы смогут преобразовать task в пассивный объект, защищённый мониторами, внутри которого бывшее тело задачи разрезано на кусочки-корутины. И что-то пошло не так. И у меня сложилось впечатление, что подобные игры со временем требуют каких-то тепличных условий, сильно неудобных, если распространять их на весь код.

    гарантии о том что нету data race, конкурентного доступаИ адские, и плюсовые контейнеры по умолчанию предлагают такой формат работы, когда способ доступа к контейнеру автоматически транслируется на его содержимое. Копирование глубокое. В отличие от Objective-C 2.0, счётчик ссылок на контейнеры не навешен.

    проверка этой безопасности на уровне компилятора, при этом без теорем пруверов и всяких доказывалок типа SPARKВ ARC проверять нечего, только транслируй. С ходом времени Rust играть не будет, я так понимаю. Значит, остаётся только пометка переменых как невалидных вместо того, чтобы ругаться на коллизии постконтракта и преконтракта идущих подряд вызовов. То есть, шило на мыло.
  • @gothicsquash, tl;dr "я делаю всё это именно так, потому что мне так нравится, а бабло для меня — не главное."

    В том-то и дело, что я пытаюсь лезть на территорию бизнеса, забивая на общепринятые правила. Если я и могу посчитать часы, то уж цена часа моей работы — NaN, поэтому вся формула накрывается. :)

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

    Про 32 метра — это совсем другой (и не серьёзный) проект: моё интернет-радио на домашнем роутере. В качестве хобби и расслабиться в программерском смысле. Понаписать лютой дичи, но чтобы она работала. При том, что затраты в этом случае стремятся к нулю, а доход в чистых деньгах за 5 лет — $30, получаем доходность, стремящуюся к бесконечности. Мечта! :D
  • @Self-Perfection, Узнал, что в Google Play теперь выше ранжируются "качественные" приложения, что включает в себя быструю работу. Это здорово, меняет культуру в нужную сторону.