Здравствуйте, greenpci, Вы писали:
G>Я хотел понять для себя, можно ли написать управляемых код, который будет таким же быстрым, как Си плюс плюс, в рамках этой задачи. На данный момент, делаю вывод, что нельзя. Будет разница в пользу плюсов. То есть плюсы бытсрее.
На Java можно получить сравнимый по скорости с C++ код. Сравнимый — означает, что разницей в быстродействии можно пренебречь, т.е. нужны специальные замеры, чтоб эту разницу заметить. С учётом, что работа программы- не только торможение на индексах, а, например, торможение на неоптимальных структурах данных C++ (да, Java по числу структурам данных кроет стандартный C++, как бык овцу). А ещё файловые операции. Добавь к этому неиллюзорную вероятность порчи памяти C++ и отсутствие встроенных средств логирования и диагностики процесса.
C быстрее, чем C++, а ASM быстрее, чем C. Спорить с очевидным может только совсем упоротый языкопоклонник. Потому узкие места расшиваются специализированными библиотеками. Возьми, как пример, 3D визуализацию- хоть заоптимизируйся, а OpenGL код, даже в софтовом режиме, отработает быстрей на порядки твоих C++ шаблонов. А ведь можно и OpenGL из Java вызывать.
G>UPD: хотя вот в этом утверждении ниже unmanaged, и уже встает вопрос, зачем тогда вообще писать на шарпе.
На шарпе писать не надо по одной простой причине- это Майкрософт. Слишком много ограничений для продакшена это накладывает.
Здравствуйте, gandjustas, Вы писали:
G>Во-вторых проценты прироста быстродействия в масштабах ФБ это десятки и сотни серверов, и это действительно стоит затраченных сотен тысяч и миллионов долларов на ЗП программистов. G>Для большинства проектов проценты прироста быстродействия останутся незамеченными и дешевле будет сделать апгрейд железа, чем заниматься оптимизацией. Поэтому утверждение что "на C++ быстрый код получить на порядки проще" не G>ЗЫ. При этом никто не сомневается что предел оптимизации программы на C++ выше, чем для C# или Java. Но достижение этого предела превышает в большинстве случаев выльется в слишком большие затраты.
...затраты,
...деньги,
...дешевле,
...дешевле
В реальных корпоративных условиях эта иллюзия экономии может стоить компаниям очень дорого. Во первых, в дотнете есть технические и не технические специалисты. Дотнет фильтрует людей гораздо хуже, чем плюсы. Там легче имитировать опыт и показаться работодателю программистом, на самом деле таковым не являясь. Вероятность, что ты наймешь действительно технического профессионала, который любит свою работу, будет выше на плюсах. А когда что-то любишь делать, работа кипит и заказчик доволен. Другими словами, си плюс плюс программист, который любит свою работу, напишет код быстрее и лучше, за счет энтузиазма, чем дотнетчик, который ее не любит.
Далее, развивая идею, дотнетчик-гуманитарий-экономист, станет начальником, от него побегут технические дотнетчики и он будет принимать не технические, а политические решения. Наймет множество ненужных заместителей, убедит начальство увеличить бюджет. И вот, он уже увеличил затраты, по сравнению с прекрасным, честным, бородатым технарем из си плюс плюс.
Ты спросишь, а при чем здесь это?! Я отвечу, а при чем здесь экономия?! Если мы говорим о реальной жизни, тогда нужно рассмотреть все ее аспекты. В том числе и этот.
G>имеет никакого смысла и верно только в контексте фейсбука\гугла и еще пары-тройки гигантов. В остальных случаях сложность оптимизации на C++ и C# (и иногда Java) сравнимы, а учитывая в общем более высокую сложность разработки на C++ еще непонятно что будет проще в итоге.
Разработка на плюсах имеет некоторую сложность, но эта сложность преувеличена. Программист, работающий на плюсах много лет, будет достаточно эффективен и не будет дороже стоить.
Здравствуйте, greenpci, Вы писали:
G>Разработка на плюсах имеет некоторую сложность, но эта сложность преувеличена.
1. Да, в некоторых местах сложнее, но тут действительно много преувеличений и бородатых мифов.
2. Не нужно забывать что C++ это не только преимущества в скорости, но ещё и в гибкости. Обобщённый код (это даже не метапрограммирование) на C++ получается короче и проще. На C# — шаг влево, шаг вправо и упираешься в забор
, в результате код получается более многословный.
Вот например, на Python можно сделать так (будет работать для любых типов имеющих соответствующие операторы):
def add(x, y):
return x + y
def sub(x, y):
return x - y
def apply(f, *args):
return f(*args)
print(apply(apply, apply, apply, add, 1, 2))
print(apply(apply, apply, sub, 11, 2))
Здравствуйте, greenpci, Вы писали: G>В реальных корпоративных условиях эта иллюзия экономии может стоить компаниям очень дорого. Во первых, в дотнете есть технические и не технические специалисты. Дотнет фильтрует людей гораздо хуже, чем плюсы. Там легче имитировать опыт и показаться работодателю программистом, на самом деле таковым не являясь. Вероятность, что ты наймешь действительно технического профессионала, который любит свою работу, будет выше на плюсах. А когда что-то любишь делать, работа кипит и заказчик доволен. Другими словами, си плюс плюс программист, который любит свою работу, напишет код быстрее и лучше, за счет энтузиазма, чем дотнетчик, который ее не любит.
В реальных корпоративных условиях эта иллюзия экономии может стоить компаниям очень дорого. Во первых, в С++ есть технические и не технические специалисты. С++ фильтрует людей гораздо хуже, чем дотнет. Там легче имитировать опыт и показаться работодателю программистом, на самом деле таковым не являясь. Вероятность, что ты наймешь действительно технического профессионала, который любит свою работу, будет выше на дотнете. А когда что-то любишь делать, работа кипит и заказчик доволен. Другими словами, дотнет программист, который любит свою работу, напишет код быстрее и лучше, за счет энтузиазма, чем плюсист, который ее не любит.
Здравствуйте, mik1, Вы писали:
M>Еще раз повторю.
M>1) Time to market уменьшается для последующих изменений. M>2) Я не думаю, что с byte[] в Яве управляться труднее, чем в плюсах. Соот-но, время и пространство не факт, что ухудшатся. M>3) То, что на Яве молотилки / near realtime делать труднее, чем на плюсах — миф.
Дааа? ))) В таком случае специалисты по быстрому коду на Java легко подскажут мне как оптимизировать до уровня нативного например такой простейший Java код:
static long Test()
{
long timer=System.currentTimeMillis();
final int width=image.length/height;//width=1920; height=1080int[] buf=(int[])image.clone();
for(int n=0; n<count; n++){//count=500for(int y=1; y<height-1; y++){
final int p=width*y;
for(int x=1; x<width-1; x++) if(image[p+x]!=0xffffff)
buf[p+x]=(image[p-width+x]+image[p+x-1]+image[p-width+x-1]+image[p-width+x+1]+image[p+width+x-1]+image[p+width+x]+image[p+x+1]+image[p+width+x+1])>>3;
}
for(int y=1; y<height-1; y++){
final int p=width*y;
for(int x=1; x<width-1; x++) if(buf[p+x]!=0xffffff)
image[p+x]=(buf[p-width+x]+buf[p+x-1]+buf[p-width+x-1]+buf[p-width+x+1]+buf[p+width+x-1]+buf[p+width+x]+buf[p+x+1]+buf[p+width+x+1])>>3;
}
}
return System.currentTimeMillis()-timer;
}
А то он что-то работает в 5 (!) раз медленнее C++ аналога.
P.S. C# версия (без фокусов с fixed, которые превращают C# в кривой аналог C) работает в 7 раз медленнее C++ кода.
Aё> На Java можно получить сравнимый по скорости с C++ код. Сравнимый — означает, что разницей в быстродействии можно пренебречь, т.е. нужны специальные замеры, чтоб эту разницу заметить. С учётом, что работа программы- не только торможение на индексах, а, например, торможение на неоптимальных структурах данных C++ (да, Java по числу структурам данных кроет стандартный C++, как бык овцу). А ещё файловые операции. Добавь к этому неиллюзорную вероятность порчи памяти C++ и отсутствие встроенных средств логирования и диагностики процесса. Aё> C быстрее, чем C++, а ASM быстрее, чем C. Спорить с очевидным может только совсем упоротый языкопоклонник. Потому узкие места расшиваются специализированными библиотеками. Возьми, как пример, 3D визуализацию- хоть заоптимизируйся, а OpenGL код, даже в софтовом режиме, отработает быстрей на порядки твоих C++ шаблонов. А ведь можно и OpenGL из Java вызывать. Aё>
Этот феерический бред сгененировал кажется тот же самый персонаж, что заявлял, что на микроконтроллерах нет C++? И который предлагал оценивать быстродействие Питона по numpy и быстройдействие Java по blas/lapack? Может стоит просто забанить его на форуме? Понятно же ведь, что это или сверхжирный тролль или школьник.
Здравствуйте, alex_public, Вы писали:
EP>>Если писать код подобным образом на Java то и будет получаться скорость очень близкая к native'у. _>А вот далеко не факт. ) _>Хотя я конечно не эксперт по оптимизациям в Java — сейчас узнаем у специалистов... )
C++ код скомпированный в JavaScript и запущенный в Firefox показывает скорость близкую к native'у — 75ms, на native C++ было 60ms, на C# — 69ms.
Если на C# использовать не низкоуровневый цикл, а transform и лямбду (как было на C++) — то получается 141ms.
В общем поинт в следующем — если в языке есть эффективная возможность работать с типизированными массивами, да ещё и чем-то типа кастов/view — то есть возможность сделать быстрый код. А чтобы такого кода много не писать (нарезать руками массивы на структуры, руками выписывать каждый цикл вместо ФВП и лямбд, и т.п.) — то в него можно скомпилировать C++, а низкоуровневой работой
b = mem_as_Int32[m >> 2] | 0;
while (1) {
u = +mem_as_Float64[a >> 3];
g = a + 8 | 0;
w = +mem_as_Float64[g >> 3];
v = +mem_as_Float64[b >> 3];
t = +mem_as_Float64[b + 8 >> 3];
mem_as_Float64[a >> 3] = u * v - w * t;
mem_as_Float64[g >> 3] = w * v + u * t;
a = a + 16 | 0;
if ((a | 0) == (c | 0)) break;
else b = b + 16 | 0
}
Здравствуйте, alex_public, Вы писали:
_>А то он что-то работает в 5 (!) раз медленнее C++ аналога. _>P.S. C# версия (без фокусов с fixed, которые превращают C# в кривой аналог C) работает в 7 раз медленнее C++ кода.
А ты сравнивал генерируемый ASM? Как сильно отличается? Точнее в чём там главный тормоз?
C++ код скомпированный в JavaScript и запущенный в Firefox показывает скорость близкую к native'у — 75ms, на native C++ было 60ms, на C# — 69ms. EP>Если на C# использовать не низкоуровневый цикл, а transform и лямбду (как было на C++) — то получается 141ms.
Если речь про работы со структурами, то возможно. Однако есть и много других нюансов...
Но техника конечно интересная. Хотя всё же C++ с его мощью и доступом ко всем мелочам выглядит очень странно в роли языка для генерации другого программного кода. )))
EP>В общем поинт в следующем — если в языке есть эффективная возможность работать с типизированными массивами, да ещё и чем-то типа кастов/view — то есть возможность сделать быстрый код. А чтобы такого кода много не писать (нарезать руками массивы на структуры, руками выписывать каждый цикл вместо ФВП и лямбд, и т.п.) — то в него можно скомпилировать C++, а низкоуровневой работой
Как минимум требуется ещё вменяемый интерпретатор (к примеру если тут взять Python вместо JS, то сомневаюсь, что получится похожий результат). Это в общем случае. А в отдельных задачах (типа моего примера выше) будут всплывать ещё различные специфические нюансы, не позволяющие приблизиться к нормальному нативному коду.
Здравствуйте, alex_public, Вы писали:
EP>>А ты сравнивал генерируемый ASM? Как сильно отличается? Точнее в чём там главный тормоз? _>Я не в курсе как заставить java/c# выдать мне ассемблерный код по исходнику. Ну а лазить с дизассемблером/отладчиком там мне точно лень. )))
Да, проще всего подсоединить отладчик во время работы того самого долгого цикла (можно добавить снаружи ещё несколько итераций чтобы успеть), отладчик VS вполне подойдёт.
C++ код скомпированный в JavaScript и запущенный в Firefox показывает скорость близкую к native'у — 75ms, на native C++ было 60ms, на C# — 69ms. EP>>Если на C# использовать не низкоуровневый цикл, а transform и лямбду (как было на C++) — то получается 141ms. _>Если речь про работы со структурами, то возможно. Однако есть и много других нюансов...
Есть, но структуры (и больший упор на value-types), статический полиморфизм, инлайнинг — это одни из основных факторов.
_>Но техника конечно интересная. Хотя всё же C++ с его мощью и доступом ко всем мелочам выглядит очень странно в роли языка для генерации другого программного кода. )))
Писать на Java в стиле ниже уровнем чем C — тоже странновато А ведь пишут же.
EP>>В общем поинт в следующем — если в языке есть эффективная возможность работать с типизированными массивами, да ещё и чем-то типа кастов/view — то есть возможность сделать быстрый код. А чтобы такого кода много не писать (нарезать руками массивы на структуры, руками выписывать каждый цикл вместо ФВП и лямбд, и т.п.) — то в него можно скомпилировать C++, а низкоуровневой работой
: _>Как минимум требуется ещё вменяемый интерпретатор (к примеру если тут взять Python вместо JS, то сомневаюсь, что получится похожий результат).
Это я и понимаю под "эффективной возможностью работать с типизированными массивами".
_>Это в общем случае. А в отдельных задачах (типа моего примера выше) будут всплывать ещё различные специфические нюансы, не позволяющие приблизиться к нормальному нативному коду.
А какие конкретно там нюансы? Там же blur через усреднение соседних восьми пикселей, так? GCC ничего необычного там не генерирует — у тебя же C++ код точно такой же? (за минусом незначительных деталей)
Можем ради интересно сравнить с C++ -> JavaScript.
Кстати, там в начале полное копирование в буфер не нужно — достаточно только краёв.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>А какие конкретно там нюансы? Там же blur через усреднение соседних восьми пикселей, так? GCC ничего необычного там не генерирует — у тебя же C++ код точно такой же? (за минусом незначительных деталей)
Почти такой же — чуть красивее (и за счёт этого ещё и эффективнее) из-за использования арифметики указателей. )
EP>Можем ради интересно сравнить с C++ -> JavaScript.
Кстати, а JS умеет SIMD (автоматический естественно)? )
Здравствуйте, alex_public, Вы писали:
EP>>Можем ради интересно сравнить с C++ -> JavaScript. _>Кстати, а JS умеет SIMD (автоматический естественно)? )
На стороне браузера, в JIT? — не знаю, думаю вряд ли.
Находятся заметки о появлении SIMD.js, то есть своего рода явные интринсинки, которые в свою очередь теоретически может использовать Emscripten (также находятся комментарии на этот счёт, но ещё не понял в каком оно состоянии).
А к чему спрашиваешь? Я сразу проверил — GCC твой код не векторизирует, по-крайней мере в таком виде.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
_>>Кстати, а JS умеет SIMD (автоматический естественно)? ) EP>На стороне браузера, в JIT? — не знаю, думаю вряд ли.
Я вот что-то задумался... А хоть один динамический язык вообще умеет автовекторизацию? )
EP>Находятся заметки о появлении SIMD.js, то есть своего рода явные интринсинки, которые в свою очередь теоретически может использовать Emscripten (также находятся комментарии на этот счёт, но ещё не понял в каком оно состоянии).
Нуу ручное для таких языков — это не интересно. )
EP>А к чему спрашиваешь? Я сразу проверил — GCC твой код не векторизирует, по-крайней мере в таком виде.
Здравствуйте, alex_public, Вы писали:
_>>>Кстати, а JS умеет SIMD (автоматический естественно)? ) EP>>На стороне браузера, в JIT? — не знаю, думаю вряд ли. _>Я вот что-то задумался... А хоть один динамический язык вообще умеет автовекторизацию? )
Не, не слышал о таком.
EP>>Находятся заметки о появлении SIMD.js, то есть своего рода явные интринсинки, которые в свою очередь теоретически может использовать Emscripten (также находятся комментарии на этот счёт, но ещё не понял в каком оно состоянии). _>Нуу ручное для таких языков — это не интересно. )
Emscripten это как раз компилятор C++ -> JS, вот пусть он и автовекторизует в эти ASM.js интринсинки.
EP>>А к чему спрашиваешь? Я сразу проверил — GCC твой код не векторизирует, по-крайней мере в таком виде. _>У меня векторизует. )
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Emscripten это как раз компилятор C++ -> JS, вот пусть он и автовекторизует в эти ASM.js интринсинки.
Да, в этом случае всё было бы нормально. Но надо признать, что всё же Emscripten — это мягко говоря не популярный инструмент. ))) Так что никто не будет вести разработку JS в расчёте на него.
EP>Значит форма всё же отличается, тогда понятно.
Конечно. Но в том то и весь смысл:
1. Как раз такая форма является наиболее естественной и удобной для подобных алгоритмов.
2. Такую форму невозможно реализовать на языках типа Java или C#. )
Здравствуйте, alex_public, Вы писали:
EP>>Emscripten это как раз компилятор C++ -> JS, вот пусть он и автовекторизует в эти ASM.js интринсинки. _>Да, в этом случае всё было бы нормально. Но надо признать, что всё же Emscripten — это мягко говоря не популярный инструмент. ))) Так что никто не будет вести разработку JS в расчёте на него.
Конечно в первую очередь это инструмент для портирования, причём успешный (Unreal Engine портировали за 4 дня, уже портированно QT и т.п.).
Тем не менее, например если нужно создать быстрый JavaScript код — то почему бы его не использовать?
EP>>Значит форма всё же отличается, тогда понятно. _>Конечно. Но в том то и весь смысл: _>1. Как раз такая форма является наиболее естественной и удобной для подобных алгоритмов. _>2. Такую форму невозможно реализовать на языках типа Java или C#. )
Странно: GCC завекторизировал исходную форму, но только в x32 (на Coliru по умолчанию было x64).