Те кто плюсуют не испытали мощь математических инструментов. Откройте для себя Octave, Maxima, Scilab, R… Или Matlab, да хотя бы и MathCad! Постройте говорящие графики в Origin или Qtiplot… И после этого откройте Excel. Желательно последней версии, в которой интерфейс предельно «упрощён» и до всех действительно продвинутых функций нужно добираться в десятки кликов. Уверяю вас вы его с ужасом закроете через несколько минут.
Проблема в том, что редактировать в latex-подобном синтаксе нельзя. Вот, например, захотелось мне заменить "*" на "\cdot". В LibreOffice это делается не задумываясь, а в MS Word? Ну или имена переменных в длинной формуле поменять. Или сконвертировать все %alpha, %beta в %ALPHA, %BETA и т.п.
А в режиме write-once (написать и забыть), да можно пользоваться и MS Office.
Это больше style-checker, а не статический анализатор кода. Просто посмотрите на заданные правила и сообщения об «ошибках»:
lintWarning(*it, "Protected inheritance is sometimes not a good "
"idea. Read "
"http://stackoverflow.com/questions/6484306/effective-c-discouraging-protected-inheritance "
"for more information.\n");
lintError(*it, "Open Source Software may not include files from "
"other fbcode projects (except folly). "
"If this is not an fbcode include, please use "
"'#include <...>' instead of '#include \"...\"'. "
"You may suppress this warning by including the "
"comment 'nolint' after the #include \"...\".\n");
Очень сложный вопрос про JEE7. Вот я пишу на Scala, основной фреймворк Scalatra, сбоку ещё Vaadin прикручен. Вроде бы не использую, но аннотации из Servlet 3.0 люблю и использую. Ответил что «Да, использую», ведь хоть какую-то часть я взял.
Зря написали про отсутствие минусов у кортежей и case-классов. Периодически спотыкаюсь на ограничение в 22 члена класса. Обычно при написании классов для ORM и других DTO.
Ещё не совсем удачно написан минус к декораторам, что в trait'ы нельзя передавать параметры конструктора. Фактически можно:
trait Buffering extends OutputStream {
def bufferSize: Int
abstract override def write(b: Byte) {
// ... buffer for bufferSize bytes
super.write(b)
}
}
new FileOutputStream("foo.txt") with Buffering { val bufferSize = 12 }
Зря вы так про «любой, кто пишет на scala больше недели». Я вот скалашный for-синтаксис не люблю (то это map, то это foreach). Мне намного приятнее читать цепочку вызовов map, чем многострочный for. Опять же, то мне map нужен, то flatMap. И ещё мне не нравится что при чтении for-expression приходится постоянно читать то слева направо, то справа налево. Вот в вашем же примере:
SoundSource.getSound.foreach(sound => sound.play() ) // всё слево направо
А уж тем более проще
<source lang=«scala>
SoundSource.getSound.foreach(_.play() )
Принципиальная разница в том, что результат String.concat() — полноценная строка. Уже само по себе плохо что это полноценный объект (который должен будет подчистить GC), так это ещё и строка — а значит она окажется в строковом кэше. Который (насколько я помню), до Full GC чистить никто не будет.
В StringBuilder'е же строка это просто char*, который Java-объектом не является.
Хм, вообще-то мой комментарий был совсем не о количестве команд в листинге. Для интереса я заменил функцию вычисления элемента с i + j на rand.nextInt(100) / (1 + rand.nextInt(100)) * rand.nextInt(100), оставив при этом весь остальной код тем же (то есть матрица по-прежнему получится диагональная). И вот результат:
One time 2072.3487 msc
Two time 1246.582756 msc
То есть оптимизировать таким образом имеет смысл если операция вычисления Mij = Mji достаточно «дорогая».
Посмотрел и дизассемблер. Ещё интересно, что JVM вынесла проверку границ за пределы цикла в «неоптимизированном» варианте. В первом варианте есть только одно место с комментарием «implicit exception», в втором их три. Я не слишком часто читают дизассемблерный код из JVM, так что дальше разбираться пожалуй не буду.
Буду следить за обновлениями в топике. Спасибо за задачку!
P.S. Ничего себе у вас задачки для (pre)juniour'ов :)
Мне кажется дело в лишнем aaload. В первом варианте компилятор работает с массивом как с одномерным. Во втором, он строго следуюет написанному коду и постоянно пихает в стек ссылку на очередной внутренний массив как на отдельный массив. Ему же надо найти g[j].
Ну и вообще получается, что раз количество операций записи у нас одинаково (мы же весь массив инициируем), то мы хотели сэкономить на вычилении каждого из элементов. Но вычисление элемента у нас один iadd, так что после «оптимизации» мы потратили больше операций вычисляя координаты в памяти куда писать.
Просто не могу удержаться и не попроавить. Как раз в Java компилятор заменит простую конктенацию вызовом StringBuilder'а. И константы заранее все соединит.
Пример
public class Test {
public static void main(String[] args) {
String s = "Some " + "string " + 1 + " concatenated: " + 2L + ":" + (byte)3 + ":" + 1.0d;
System.out.println(s);
String s2 = "Another one " + args[0] + args[1] + args[2] + args[3];
System.out.println(s2);
}
}
Солить нужно всегда. В отличие от подключения современных хэш-функций (которых может не быть в стандартной библиотеке используемого языка/фреймворка), для соления паролей вообще не надо никаких трудозатрат.
И дальше сразу же нашёл баг. Не знаю сколько бы я ещё избегал использования xfrun4 без статьи… :)
А в режиме write-once (написать и забыть), да можно пользоваться и MS Office.
Вот в вашем же примере:
Вот так читабельнее:
А уж тем более проще
Ещё не совсем удачно написан минус к декораторам, что в trait'ы нельзя передавать параметры конструктора. Фактически можно:
SoundSource.getSound.foreach(sound => sound.play() ) // всё слево направо
А уж тем более проще
<source lang=«scala>
SoundSource.getSound.foreach(_.play() )
А вообще, если вы так понимаете задачу, то вот этот код тоже подойдёт:
Всё. Я «заполнил» массив нулями. Ноль вполне себе «что угодно».
В StringBuilder'е же строка это просто char*, который Java-объектом не является.
Раз уж у нас тут ветка ликбеза получается…
То есть оптимизировать таким образом имеет смысл если операция вычисления Mij = Mji достаточно «дорогая».
Буду следить за обновлениями в топике. Спасибо за задачку!
P.S. Ничего себе у вас задачки для (pre)juniour'ов :)
А в варианте один только
Мне кажется дело в лишнем aaload. В первом варианте компилятор работает с массивом как с одномерным. Во втором, он строго следуюет написанному коду и постоянно пихает в стек ссылку на очередной внутренний массив как на отдельный массив. Ему же надо найти g[j].
Ну и вообще получается, что раз количество операций записи у нас одинаково (мы же весь массив инициируем), то мы хотели сэкономить на вычилении каждого из элементов. Но вычисление элемента у нас один iadd, так что после «оптимизации» мы потратили больше операций вычисляя координаты в памяти куда писать.
$ javac Test.java && javap -c Test
Конечно если строка конкатенируется в цикле или в разных методах, то компилятор уже не спасёт.