Ява: int->String
А как тогда инт в стринг преобразовать, не генеря объектов? Можно ли PrintWriter как-то прикрутить к работе с файлами?Printwriter тут тебе никак не поможет,потому что он неявно так же создает обертку для примитивных типов ,а потом преврящает их в строку.
Ты не парься по поводу засирания оперативки- gc все удалит , когда время придет
А если уж очень охота сэкономить - то пиши в файл не строки а прям интежеры.
яву с основКак можно не зная даже основ Явы рассуждать о производительности отдельных конструкций? Ты может быть исходники используемой тобой JVM читал?
int n = 10;
n+"\n";
вообщето библиотеки в составе языка поставляются с исходными текстами, поэтому читать их, когда что то непонятно- это обычная практика
Можно еще круче написать:
FileWriter fw = new FileWriter("Out");
String out = "";
for(int i=0;i<N;i++)
{
Integer rnd = new Integerint100*Math.random;
out = out + rnd.toString+"\n";
}
fw.write(out);
fw.close;
Тогда будет создано в два раза больше объектов!
Ну, то что String'и лишние создадутся при "+" я и так догадываюсь. Облажался, конешно, лучше, наверно fw.write(s);fw.write("\n"); Но вопрос-то в другом!
В чём вопрос? Сборщик запустится только тогда, когда это будет необходимо. Есть два варианта запуска java, в которых сборщик работает по-разному: как интерактивное приложение или как серверное. В твоём конкретном примере сборщик отработает настолько быстро, что никому от этого плохо не станет. Да и вообще сложно придумать пример, когда языки со сборщиком мусора потеряют производительность из-за создания кучи объектов. В конце-концов, они все под это заточены.
Integer.toString(n)
Это не ответ на вот эту часть вопроса: "не генеря объектов". Думаю, что ответ как раз: "никак".
а так?
for (int i = 1000000; i > 0; i/=10)
{
fw.write('0'+n/i);
n = n % i;
}
Ну я так и предложил, но мне кажется, что '0'+n/i у тебя делает новый объект String.
Автору поста же ботать PrintWriter-ы.
а строка откуда тогда берется? из параллельного мира?
он делает новый char, а не string
а char - это всего лишь доп. локальная переменная (или, вообще, регистр а не объект.
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(0, size, buf);
}
Да, ты прав. Но если ты поглядишь как оно печатает int, то у тебя там всё равно создаётся String. А самым точным ответом на вопрос, может быть JNI. Наверно.
но, я то печатаю char, а не int
строка вроде не должна создаваться.
switch(i) {
case Integer.MIN_VALUE: return "-2147483648";
case -3: return "-3";
case -2: return "-2";
case -1: return "-1";
case 0: return "0";
case 1: return "1";
case 2: return "2";
case 3: return "3";
case 4: return "4";
case 5: return "5";
case 6: return "6";
case 7: return "7";
case 8: return "8";
case 9: return "9";
case 10: return "10";
}
char[] buf = (char[]perThreadBuffer.get;
int charPos = getChars(i, buf);
return new String(buf, charPos, 12 - charPos);
Короче, забейте на оптимизацию.
Сложение чаров = инт. Хотя печать инта может сразу попасть на вывод (в native code согласен.
Этот код у тебя какой давности?
Забыл
тогда так (смысл в том, что печатать по одну символу, overhead-а, конечно, больше, зато никаких новых объектов):
for (int i = 1000000; i > 0; i/=10)
{
fw.writechar'0'+n/i;
n = n % i;
}
Да, так можно. Сдаётся мне, пока оно будет печатать таким образом, сборщик мусора успеет раза два-три отработать. %)
С чего бы это вдруг? Всего около 7 итераций. Хотя скорость зависит от write конечно.
Если Writer не буферизированный, то точно успеет.
Да, возможно.
Короче, мораль такая, что нефиг заботиться о том, о чём уже позаботились. Код для алокации и удаления объектов и строк, быстро и от балды написанный на С++, будет работать медленее, чем Джава. (Конечно, можно написать на С++, чтобы было быстрее, я этого не отрицаю. Но задача будет нетривиальной.)
Даже если буферизированный, то overhead-ы на лишние вызовы write-ов скорее всего будут выше, чем однократный пробег GC по уборке нагенеренных строк.
все-таки от лишних аллокаций лучше, конечно, избавляться. те же сложения строк лучше по реже делать, если возможно.
но в то же время, согласен, что сильно заморачиваться этим не стоит.
а бреки кто будет ставить?
все-таки от лишних аллокаций лучше, конечно, избавляться.Я помню, года 4 назад была повальная мода на пулы объектов, любой ORM работал через пул.
В последнее время народ постепенно начинает дозревать, что затраты на пул в современных JVM могут оказаться существенно выше чем создание короткоживущих объектов.
В частности, JDK 1.5 вышел с новым heap layout, где очень много сил брошено на оптимизацию короткоживущих объектов (по статистике Sun - до 90% объектов короткоживующие).
там ретурны стоят
но про лишние аллокации речь идет про следующие случаи:
string result = "";
for (int i = 0; i < 1000; ++i)
{
result += i.ToString;
}
return result;
вот здесь аллокаций много и все они лишние.
афтару: на языках, таких как Java , C# и т.д. не стоит сильно заботить о таких мелочах. Они специально созданы , чтоб проггеры не придумывали каждый раз велосипед и собстственные "крутые" методы, теряя на это время и допуская ошибки. Лучше вечером попить пивка ,чем часами тестировать собственные творения.
Возможно, что-то на этот счет придумали в Mustang, где куча всяких наворотов с оптимизацией.
Понятно, что X = A + B + C; будет свернут в StringBuffer, с циклами сложнее.
Опять же, рискуя нарваться на Глебиуса, скажу, что оптимизировать надо все-таки с профайлером в руках, а не абы как.
Полностью согласен.
Это зачот б/п. Слава богу, что мой любимый софт не пишут в россии.
А где? В Индии?
А мой любимый софт - IntelliJ IDEA - пишут в России!
Оставить комментарий
salko1
Взялся тут изучать яву с основ. Придумываю-пишу всякие ламерские примерчики, в частности прогу, которая генерит N случайных интов, и в файл записывает. Получилось что-то типа:Работать-то работает, но есть вопросы: Получается, что в результате работы такого цикла сгенерируется N Integer'ов и N String'ов в куче (или как это в яве называется ) Следовательно, как я понимаю, будет потеря производительности, так как, замусорив память, мы "приблизим" момент сборки мусора? А как тогда инт в стринг преобразовать, не генеря объектов? Можно ли PrintWriter как-то прикрутить к работе с файлами?