Проблема ещё в том, что я и не математик вовсе. Поэтому с большой вероятностью всё что я придумываю в математике — это велосипеды. Но как гимнастика для мозгов вполне годится.
Т.е. наличие двух условий никак не влияет на результат функции, функция всегда возвращает одно и то же.
А отдельного предупреждения "функция всегда возвращает одно и то же" нету? Понятно, его придётся тюнить, например, если предполагается, что метод будет перегружаться или наоборот это метод из реализации интерфейса и по спецификации он должен что-то возвращать. Но, я думаю, можно найти баланс, чтобы ложных сработок почти не было.
IDEA так не делает, не надо инсинуаций. Эта инспекция по умолчанию в режиме information-only (то есть код не жёлтый, но по Alt+Enter фикс доступен). Если вы её сами включили в своём проекте, IDEA не виновата. Если вы не включали и она вам подсвечивает на только что созданном проекте, то, пожалуйста, сообщите нам.
Как я понимаю, это не сам Unicode стандарт символов, а некий дополнительный проект консорциума Unicode — [CLDR](http://cldr.unicode.org/index), который в целом направлен на стандартизацию интернационализации приложений. Мотивация понятна — удобно, когда можно в одной строчке закодировать все настройки, с которыми необходимо вывести данное сообщение в интерфейсе конкретному пользователю.
Ну StringBuilder — это не оптимизация, а необходимость, потому что специального байткода для конкатенации строк нет. Раз ее знаете, то я вам говорю: оптимизации делает оптимизирующий JIT-компилятор, который работает в рантайме. Javac ничего не оптимизирует, если не считать минимального фолдинга констант и удаления недостижимых веток в соответствии с JLS.
Это с одной стороны. А с другой при большом наплыве даже короткоживущих объектов потребуется более частая аллокация новых TLAB'ов и в итоге более частые вызовы minor GC (пусть и работы им не прибавится). В общем, нет простых ответов, всё надо измерять.
что метод не возвращает управление нормальным образом.
В данном случае это не применимо. Метод checkIndex может вернуть управление нормальным образом в зависимости от параметров. Если ему передавать вторым параметром 0, тогда не может.
Не думаю, что авторы этой фичи руководствовались теорией категорий. Скорее практическими соображениями, что где null'ы, там баги. Но три минуса вам действительно многовато, разбавил.
Читаю наплывами только то что интересно. Просто список изменений потребовалось составить по работе, ну и я сюда его кинул, снабдив комментариями, чтобы другим людям тоже польза была.
Я не знаю таких оптимизаций в JVM, которые бы удаляли new в момент компиляции.
Ну если вы не знаете, это же не значит, что их нет.
то я бы конечно выбрал реализацию, где объектов выделяется меньше.
Такое чувство, что вам просто не нравятся объекты сами по себе. Не там вы ищете узкое место производительности, совсем не там.
Напоминает мне людей, которые говорили, что IntStream.range(0, 100).forEach(System.out::println) ужасно тормозит по сравнению с for(int i=0; i<100; i++) System.out.println(i); и тоже рассуждали про кучу объектов, про ужасно развесистую реализацию стримов, про то что method-reference разворачивается в класс в рантайме. При этом никого не волнует, что каждый вызов System.out.println на несколько порядков медленнее всего остального (а если он пишет в системную виндовую консоль, то это вообще капец). Просто потому что println — это старый добрый знакомый метод, а стримы — новое, а значит неизвестное и страшное.
Возражение №1: А что если вам только кажется, что объект выделяется? Если в коде написано new, это ещё не означает, что объект действительно выделится.
Возражение №2: А что если накладные расходы на выделение объекта настолько малы, что составляют 0.0001% от производительности программы, но при этом уберегают вас от возможных ошибок, которые бы вы совершили, если бы API выделяло меньше объектов? Если же вы не готовы пожертвовать даже 0.0001% производительности, тогда вам не следует писать на Java, потому что вы уже жертвуете гораздо большим процентом.
Lazy init в случае List0 совершенно не нужен. Вы, видимо, плохо понимаете вообще, когда он нужен. Если не бывает обращений к классу без обращений к инстансу синглтона, то смысла в lazy init никакого. Тут как раз такой случай.
И к чему нужна была такая вот реализация? Этот вопрос все еще для меня открыт.
Лучше сразу в публичном API сделать оверлоады, а потом дооптимизировать реализацию, если необходимо. Это можно сделать даже в минорных апдейтах, и ваша программа автоматически станет быстрее (даже без перекомпиляции). Ну и байткод короче будет у вас, что иногда полезно.
Звучит разумно, спасибо за комментарий!
В задаче с окантовкой ширины в одну клетку (и вообще фиксированной ширины) такие тройки не подойдут. А разбирая более общую задачу я это ниже отметил:
А отдельного предупреждения "функция всегда возвращает одно и то же" нету? Понятно, его придётся тюнить, например, если предполагается, что метод будет перегружаться или наоборот это метод из реализации интерфейса и по спецификации он должен что-то возвращать. Но, я думаю, можно найти баланс, чтобы ложных сработок почти не было.
IDEA так не делает, не надо инсинуаций. Эта инспекция по умолчанию в режиме information-only (то есть код не жёлтый, но по Alt+Enter фикс доступен). Если вы её сами включили в своём проекте, IDEA не виновата. Если вы не включали и она вам подсвечивает на только что созданном проекте, то, пожалуйста, сообщите нам.
Ну StringBuilder — это не оптимизация, а необходимость, потому что специального байткода для конкатенации строк нет. Раз ее знаете, то я вам говорю: оптимизации делает оптимизирующий JIT-компилятор, который работает в рантайме. Javac ничего не оптимизирует, если не считать минимального фолдинга констант и удаления недостижимых веток в соответствии с JLS.
А что, Java какие-то оптимизации делает не в рантайме?
Кушайте на здоровье, если сами гуглить не умеете.
В данном случае это не применимо. Метод checkIndex может вернуть управление нормальным образом в зависимости от параметров. Если ему передавать вторым параметром 0, тогда не может.
Читаю наплывами только то что интересно. Просто список изменений потребовалось составить по работе, ну и я сюда его кинул, снабдив комментариями, чтобы другим людям тоже польза была.
— Вы уверены?
— Конечно! Когда я писал «B» с использованием «C», а потом перешёл на «D», то стало медленнее. Значит, «A» тормозит.
Ну если вы не знаете, это же не значит, что их нет.
Такое чувство, что вам просто не нравятся объекты сами по себе. Не там вы ищете узкое место производительности, совсем не там.
Напоминает мне людей, которые говорили, что
IntStream.range(0, 100).forEach(System.out::println)
ужасно тормозит по сравнению сfor(int i=0; i<100; i++) System.out.println(i);
и тоже рассуждали про кучу объектов, про ужасно развесистую реализацию стримов, про то что method-reference разворачивается в класс в рантайме. При этом никого не волнует, что каждый вызовSystem.out.println
на несколько порядков медленнее всего остального (а если он пишет в системную виндовую консоль, то это вообще капец). Просто потому чтоprintln
— это старый добрый знакомый метод, а стримы — новое, а значит неизвестное и страшное.Возражение №1: А что если вам только кажется, что объект выделяется? Если в коде написано
new
, это ещё не означает, что объект действительно выделится.Возражение №2: А что если накладные расходы на выделение объекта настолько малы, что составляют 0.0001% от производительности программы, но при этом уберегают вас от возможных ошибок, которые бы вы совершили, если бы API выделяло меньше объектов? Если же вы не готовы пожертвовать даже 0.0001% производительности, тогда вам не следует писать на Java, потому что вы уже жертвуете гораздо большим процентом.
Lazy init в случае List0 совершенно не нужен. Вы, видимо, плохо понимаете вообще, когда он нужен. Если не бывает обращений к классу без обращений к инстансу синглтона, то смысла в lazy init никакого. Тут как раз такой случай.
Вы измеряли реальный GC pressure от использования time API в реальных сценариях? Или так сорцы почитали и сразу поняли, что всё будет тормозить?
Лучше сразу в публичном API сделать оверлоады, а потом дооптимизировать реализацию, если необходимо. Это можно сделать даже в минорных апдейтах, и ваша программа автоматически станет быстрее (даже без перекомпиляции). Ну и байткод короче будет у вас, что иногда полезно.