E__>>В принципе, java вообще может ставиться простым копирпованием(и отлично работать) CC>Где взять Java.rar который достаточно тупо распаковать в папку и чтоб больше нигде и ничего?
Тебе под какую платформу? Виндовс, как я понимаю, но 32 или 64? Запакую, выложу.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, Eugeny__, Вы писали:
E__>>>В принципе, java вообще может ставиться простым копирпованием(и отлично работать) CC>>Где взять Java.rar который достаточно тупо распаковать в папку и чтоб больше нигде и ничего?
E__>Тебе под какую платформу? Виндовс, как я понимаю, но 32 или 64? Запакую, выложу.
Пофигу в общем то. Есть и та и та.
Но удобнее наверное всё таки под 32
Thanks, панимаш, in advance
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, Eugeny__, Вы писали:
E__>>>>В принципе, java вообще может ставиться простым копирпованием(и отлично работать) CC>>>Где взять Java.rar который достаточно тупо распаковать в папку и чтоб больше нигде и ничего?
E__>>Тебе под какую платформу? Виндовс, как я понимаю, но 32 или 64? Запакую, выложу. CC>Пофигу в общем то. Есть и та и та. CC>Но удобнее наверное всё таки под 32 CC>Thanks, панимаш, in advance
Только учти, что это моя домашняя машина, потому кабель могут перевтыкнуть в ноут, и ресурс будет недоступен. А так — с пылу, с жару, свеженькая jdk для win32.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, Eugeny__, Вы писали:
E__>http://89.252.61.184/jdk.rar E__>Только учти, что это моя домашняя машина, потому кабель могут перевтыкнуть в ноут, и ресурс будет недоступен. А так — с пылу, с жару, свеженькая jdk для win32.
Ага, пасиба, стянул.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
А нет ли на этом этапе существенной разницы с С++ тестом?
std::string то на каждую строку честно хранит отдельную копию содержимого. Нет ли тут со стороны Java меньшего колва аллокаций?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Твой пример кода на Java функционально не эквивалентен С++ варианту. Ибо std строки в С++ суть массивы, которые при копировании как ни странно честно копируются. А в Java строки суть иммутабельные объекты, при копировании которых реального выделения памяти не происходит.
Что с точки зрения замера скорости аллокаций нам не подходит в принципе.
Почему бы не сравнивать вот такой вариант:
import java.util.ArrayList;
public class Foo {
int m_x;
int m_y;
char[] m_s;
char[] m_f;
char[] m_o;
char[] m_i;
char[] m_r;
char[] m_b;
char[] m_a;
static char[] value = "This is a test for Allocations".toCharArray();
public Foo(int x, int y) {
m_x = x;
m_y = y;
m_s = new char[value.length]; System.arraycopy(value, 0, m_s, 0, value.length);
m_f = new char[value.length]; System.arraycopy(value, 0, m_f, 0, value.length);
m_o = new char[value.length]; System.arraycopy(value, 0, m_o, 0, value.length);
m_i = new char[value.length]; System.arraycopy(value, 0, m_i, 0, value.length);
m_r = new char[value.length]; System.arraycopy(value, 0, m_r, 0, value.length);
m_b = new char[value.length]; System.arraycopy(value, 0, m_b, 0, value.length);
m_a = new char[value.length]; System.arraycopy(value, 0, m_a, 0, value.length);
}
public static void test() {
ArrayList<Foo> list = new ArrayList<Foo>();
long time = System.currentTimeMillis();
for(int i = 0; i < 80000; i++) {
list.add(new Foo(i, i));
}
System.out.println("" + (System.currentTimeMillis() - time) + ", " + list.size());
}
public static void main(String[] args) {
for(int f=0;f<30;++f)
test();
}
}
#include <list>
#include <string>
#include <stdio.h>
// эти defines для быстрой смены типа контейнера строк (замерял скорость работы wstring, immutable refcounted строк и ещё парой реализаций)#define STRING std::string
#define VALUE value
static STRING VALUE ("This is a test for Allocations");
class foo
{
public:
foo(int x, int y)
{
m_x = x;
m_y = y;
m_s = VALUE;
m_f = VALUE;
m_o = VALUE;
m_i = VALUE;
m_r = VALUE;
m_b = VALUE;
m_a = VALUE;
}
private:
int m_x;
int m_y;
STRING m_s;
STRING m_f;
STRING m_o;
STRING m_i;
STRING m_r;
STRING m_b;
STRING m_a;
};
void test ()
{
std::list<foo> lst;
Duration timer; // Замерялка через RDTSC, более точная
timer.Start ();
for (int i=0;i<80000;i++)
lst.push_back (foo(i,i));
timer.End ();
printf("%f, %i\n", timer.GetSeconds ()*1000.0, lst.size());
}
int main()
{
for (int i=0;i<30;i++)
test ();
}
Строка специально выбрана подлиннее чтоб убрать воздействие буфера для маленьких строк в std::string и заставить всегда использовать аллокатор.
Здравствуйте, CreatorCray, Вы писали:
CC>Точности таймера не хватает для правильного замера. Да и бросает как то очень сильно. CC>Есть какой либо более точный жабатаймер?
System.nanoTime() в наносекундах. В Линуксе, кстати, и System.currentTimeMillis() вполне с хорошей точностью.
CC>А нет ли на этом этапе существенной разницы с С++ тестом? CC>std::string то на каждую строку честно хранит отдельную копию содержимого. Нет ли тут со стороны Java меньшего колва аллокаций?
Будет.
Здравствуйте, CreatorCray, Вы писали:
CC>Твой пример кода на Java функционально не эквивалентен С++ варианту. Ибо std строки в С++ суть массивы, которые при копировании как ни странно честно копируются. А в Java строки суть иммутабельные объекты, при копировании которых реального выделения памяти не происходит. CC>Что с точки зрения замера скорости аллокаций нам не подходит в принципе. CC>Почему бы не сравнивать вот такой вариант:
Ок. Хотя arraycopy можно убрать — массивы в Java зануляются автоматически. Впрочем, пофиг, оно не влияет почти.
Здравствуйте, legogogo, Вы писали:
L>Расскажи тогда, как сборщик мусора в Java узнаёт какие объекты нужно удалят если подсчёт ссылок на эти объекты он не ведёт? L>Чёрная магия?
Подсчет ссылок — лишь один из вариантов реализации сборки мусора, причем самый примитивный. Настолько примитивный, что некоторые даже не считают это полноценной сборкой мусора, т.к. невозможно разрулить циклические ссылки, что будет приводить к утечкам памяти.
Наиболее прогрессивный вариант GC — это, к примеру, алгоритм mark and sweep. Епт, даже в ДжаваСкрипте не используется подсчет ссылок.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Наиболее прогрессивный вариант GC — это, к примеру, алгоритм mark and sweep. Епт, даже в ДжаваСкрипте не используется подсчет ссылок.
CPU stats:
Kernel time : [0:00:00.1562500], [0.156250 secs]
User time : [0:00:02.5625000], [2.562500 secs]
Total time : [0:00:02.7187500], [2.718750 secs]
Memory stats:
Page faults count : [ 64'755]
Peak pagefile usage : [ 306'028'544] bytes
Peak virtual size : [ 687'284'224] bytes
Peak working set size : [ 256'815'104] bytes
Ёй! Потребление памяти больше в ~2 раза относительно incremental GC и в ~5.4 раза относительно С++
Работа GC выполняется во втором потоке, так что по сути тут мы читерим, пряча это время.
CPU stats:
Kernel time : [0:00:00.0000000], [0.000000 secs]
User time : [0:00:00.7968750], [0.796875 secs]
Total time : [0:00:00.7968750], [0.796875 secs]
Memory stats:
Page faults count : [ 10'416]
Peak pagefile usage : [ 42'315'776] bytes
Peak virtual size : [ 48'046'080] bytes
Peak working set size : [ 42'733'568] bytes
Но поскольку это не generic аллокатор то рассматривать его не будем. По крайней мере до тех пор пока меня не вштырит написать на его основе полноценный generic аллокатор.
C>Чудес не бывает.
Ага. Именно поэтому жаба так и не показала обещаного 10х.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
CC>Ёй! Потребление памяти больше в ~2 раза относительно incremental GC и в ~5.4 раза относительно С++
Где-то раза в 2.5 в реальности больше будет занимать. Тут очень сильный оверхед на заголовки объектов и т.п.
CC>Работа GC выполняется во втором потоке, так что по сути тут мы читерим, пряча это время.
Нет, это параллельный GC, а не конкурентный. Он останавливает программу на время сборки мусора, но выполняет сборку в несколько потоков одновременно. Конкурентный GC здесь показывает очень плохие результаты — он не справляется с таким потоком мусора.
CC>Ну? Где те самые 10х, о наличии которых нам столько твердили большевики? CC>Но поскольку это не generic аллокатор то рассматривать его не будем. По крайней мере до тех пор пока меня не вштырит написать на его основе полноценный generic аллокатор.
ThreadPool — это будет не generic-аллокатор. Объекты из него не разделяются между потоками, нельзя освободить их из другого потока и т.п. В Java у нас полностью общий аллокатор.
Кроме того, общий аллокатор из чего-то типа ThreadPool'а быстрым сделать невозможно из-за необходимости межпоточной синхронизации в том или ином виде. В Java её нет вообще на этапе выделения.
Это всё, кстати, скорость создания объектов в Java реально отражается на практике. Скажем, компиляторы на Java можно писать более быстрые, чем на С++. Как раз из-за того, что манипуляции со сложными деревьями объектов можно делать быстро и потокобезопасно.
C>>Чудес не бывает. CC>Ага. Именно поэтому жаба так и не показала обещаного 10х.
Так ведь показала, по сравнению с обычным аллокатором.
Здравствуйте, Cyberax, Вы писали:
CC>>Ну? Где те самые 10х, о наличии которых нам столько твердили большевики? CC>>Но поскольку это не generic аллокатор то рассматривать его не будем. По крайней мере до тех пор пока меня не вштырит написать на его основе полноценный generic аллокатор. C>ThreadPool — это будет не generic-аллокатор.
Почему это вдруг? Очень даже аллокатор генерала пурпоса
C> Объекты из него не разделяются между потоками
Нет. Выделил в одном потоке — юзай в любом. Или ты под разделением между потоками что то другое имел в виду?
C> нельзя освободить их из другого потока
Можно. В чём проблема то?
C>Кроме того, общий аллокатор из чего-то типа ThreadPool'а быстрым сделать невозможно из-за необходимости межпоточной синхронизации в том или ином виде.
Камрад, ты меня такими заявлениями как минимум удивляешь.
ThreadPool не нуждается в межпоточной синхронизации by design. Каждый поток имеет свой собственный пул, из которого выделяется память, запрошенная этим потоком.
Освобождение памяти, выделенной другим потоком осуществляется путём добавления освобождаемого блока в interlocked single linked list, который родной поток при обращению к аллокатору забирает одним CAS и у себя уже их освобождает обычным путём.
C>Это всё, кстати, скорость создания объектов в Java реально отражается на практике. Скажем, компиляторы на Java можно писать более быстрые, чем на С++. Как раз из-за того, что манипуляции со сложными деревьями объектов можно делать быстро и потокобезопасно.
Ахха. Помниццо как то я встраивал жаббу в одну прогу в качестве скриптового языка (дёргал написанные на жаббе классы через JNI). Так вот был выбор или родной SUN компилер, написанный на жаббе или native jvc.exe из комплекта MSJava. Микрософтовский компилер порвал в брызги жабий как по скорости работы так и по потребляемым ресурсам.
Если использовать хреново подходящие примитивы то что на жабе что на С++ производительность будет хреновой.
C>>>Чудес не бывает. CC>>Ага. Именно поэтому жаба так и не показала обещаного 10х. C>Так ведь показала, по сравнению с обычным аллокатором.
Ещё раз:
стандартный GC в сравнении со стандартным WinHeap:
CPU stats:
Kernel time : [0:00:00.4218750], [0.421875 secs]
User time : [0:00:08.1093750], [8.109375 secs]
Total time : [0:00:08.5312500], [8.531250 secs]
Memory stats:
Page faults count : [ 212'163]
Peak pagefile usage : [ 32'120'832] bytes
Peak virtual size : [ 72'232'960] bytes
Peak working set size : [ 32'878'592] bytes
Где 10х?
У стандартного минимум — 197 мс. У жаббы — 150. Это 1.31х
Или ты предлагаешь сравнивать затюненую вручную (-server -XX:+UseParallelGC) жабу с default mode WinHeap?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
C>>ThreadPool — это будет не generic-аллокатор. CC>Почему это вдруг? Очень даже аллокатор генерала пурпоса
Не особо.
C>> Объекты из него не разделяются между потоками CC>Нет. Выделил в одном потоке — юзай в любом. Или ты под разделением между потоками что то другое имел в виду?
Выделил в одном, уничтожил в другом, помутировав немного. Или чтобы объект в одном потоке пережил срок жизни пула объектов в другом потоке.
C>> нельзя освободить их из другого потока CC>Можно. В чём проблема то?
Intelocked-операции всю скорость съедят. В моём тесте с С++ один только interlocked exchange на refcounter'е в std::string уже тормозит больше, чем код на Java.
Кроме того, в С++ refcounted-объекты тоже постоянно приходится использовать, а уж там полные тормоза по сравнению с GC в многопоточных программах.
C>>Это всё, кстати, скорость создания объектов в Java реально отражается на практике. Скажем, компиляторы на Java можно писать более быстрые, чем на С++. Как раз из-за того, что манипуляции со сложными деревьями объектов можно делать быстро и потокобезопасно. CC>Ахха. Помниццо как то я встраивал жаббу в одну прогу в качестве скриптового языка (дёргал написанные на жаббе классы через JNI). Так вот был выбор или родной SUN компилер, написанный на жаббе или native jvc.exe из комплекта MSJava. Микрософтовский компилер порвал в брызги жабий как по скорости работы так и по потребляемым ресурсам.
Ой, ну ты ещё Java 1 с интерпретатором вспомни. С тех пор много воды утекло.
Тогда ещё был Jikes — быстрый компилятор Java на С++. Где-то года четыре назад только Eclipse'овый компилятор стал работать в разы быстрее jikes'а.
CC>Где 10х?
С -XX:+UseParallelGC.
CC>У стандартного минимум — 197 мс. У жаббы — 150. Это 1.31х CC>Или ты предлагаешь сравнивать затюненую вручную (-server -XX:+UseParallelGC) жабу с default mode WinHeap?
У меня, к примеру, -XX:+UseParallelGC включается автоматически (внутри JVM встроены эвристики по выбору механизма GC, которые не всегда адекватны). Тут особого тюнинга как бы и нет. Тюнинг — это подбор размеров поколений, tenured-объектов и т.п. Опять же, тест абсолютно искусственный на 100%, так что неудивительно, что стандартные настройки ведут себя неадекватно.
Вот из моего проекта настройки: "-Xms512m -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=25 -XX:NewSize=5m -XX:MaxNewSize=15m -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=80 -XX:-UseConcMarkSweepGC -XX:-CMSIncrementalMode -XX:+UseParallelOldGC -XX:+UseCompressedOops" — это вот уже тюнинг.
Я работал с Hoard — это самый быстрый аллокатор для многопоточных систем, так даже он тормознее Java. Причём современные GC масштабируются почти линейно с ростом процессоров, а вот аллокаторы умирают рано или поздно на блокировках.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Nik_1, Вы писали:
N_>>Производительность 99% кода неособо вожна, но когда в приложении вдруг возникнет проблема с перфомонсом, то этот 1% кода в плюсах можно оптимизировать и получить требуемый результат, а в жаве нет В плюсах и алокатор можно на свой очень быстрый свой поставить, и строки более умные использовать, и исбавиться лишнего копирования перейдя на указатели на обьекты — и будет этот код менее милисекунды работать. А вот в джаве если упрешся в перфоманс — ничего сделать с этим не сможешь.
I>И ради этого 1% тебе надо постоянно, чт бы ты не писал, думать о тысячах мелочей.
Почему? Ради этого 1% можно в 99% кода юзать std::string и не заморачиваться о тысячах мелочей. А в 1% написать свою string.
I>В джаве можно сосредоточиться на более высокоуровневой оптимизации.
И? В си плюс плюс тоже можно. А вот с низкоуровневой — в жабе нельзя.
Здравствуйте, пыщьх, Вы писали:
I>>И ради этого 1% тебе надо постоянно, чт бы ты не писал, думать о тысячах мелочей. П>Почему? Ради этого 1% можно в 99% кода юзать std::string и не заморачиваться о тысячах мелочей. А в 1% написать свою string.
Кроме std::string приходится использовать и другие стринги.
I>>В джаве можно сосредоточиться на более высокоуровневой оптимизации. П>И? В си плюс плюс тоже можно. А вот с низкоуровневой — в жабе нельзя.
Тоже можно Издержки разные, на порядок по времени например только из за медленной компиляции.
Здравствуйте, Cyberax, Вы писали:
C>>> Объекты из него не разделяются между потоками CC>>Нет. Выделил в одном потоке — юзай в любом. Или ты под разделением между потоками что то другое имел в виду? C>Выделил в одном, уничтожил в другом, помутировав немного. Или чтобы объект в одном потоке пережил срок жизни пула объектов в другом потоке.
Это всё есть.
C>>> нельзя освободить их из другого потока CC>>Можно. В чём проблема то? C>Intelocked-операции всю скорость съедят. В моём тесте с С++ один только interlocked exchange на refcounter'е в std::string уже тормозит больше, чем код на Java.
Интерлокед там 1 на деаллокацию и только в случае деаллокации из не родного потока. Это довольно редкий сценарий.
CC>>Где 10х? C>С -XX:+UseParallelGC.
Тогда я имею полное право использовать ThreadPoolAlloc. Так что всё равно нету 10х.
C>Причём современные GC масштабируются почти линейно с ростом процессоров,
Ты Hoard точно использовал? У них даже на сайте висят графики про его масштабирование на процессора.
C>а вот аллокаторы умирают рано или поздно на блокировках.
Да не используют уже давно блокировки. Те же Hoard, TBB.
Блокировки относятся к тому же периоду что и ранние GC.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
C>>Intelocked-операции всю скорость съедят. В моём тесте с С++ один только interlocked exchange на refcounter'е в std::string уже тормозит больше, чем код на Java. CC>Интерлокед там 1 на деаллокацию и только в случае деаллокации из не родного потока. Это довольно редкий сценарий.
Там их больше будет. Например, для возврата объекта в "родной" пул и т.п.
Получается очень и очень непростой дизайн аллокатора.
CC>>>Где 10х? C>>С -XX:+UseParallelGC. CC>Тогда я имею полное право использовать ThreadPoolAlloc. Так что всё равно нету 10х.
Так я ведь задизайню тест, где у тебя всё будет сливать моему
C>>Причём современные GC масштабируются почти линейно с ростом процессоров, CC>Ты Hoard точно использовал? У них даже на сайте висят графики про его масштабирование на процессора.
Да, использовал. Графики — это конечно хорошо, но практика от теории слегка отличалась. У Hoard'а были паталогические случаи, когда он умирал при некоторых шаблонах использования, приходилось их обходить.
C>>а вот аллокаторы умирают рано или поздно на блокировках. CC>Да не используют уже давно блокировки. Те же Hoard, TBB. CC>Блокировки относятся к тому же периоду что и ранние GC.
Неа. Ты ну никак не можешь сделать многопоточный аллокатор без блокировок (sleeping mutexes) и/или атомарных операций. Java читит из-за того, что там не надо учитывать созданные объекты.