Кто-нибудь пробовал автоматическое преобразование Java в C++ для повышения скорости? Является ли это кошмаром для обслуживания в долгосрочной перспективе? Просто прочитайте, что используется для генерации движка синтаксического анализа HTML5 в Gecko http://ejohn.org/blog/html-5-parsing/Автоматическое преобразование Java в C++
ответ
В целом автоматическое преобразование с одного языка на другой не будет улучшением. Различные языки имеют разные идиомы, которые влияют на производительность.
Простейший пример - это создание циклов и создание переменных. В мире Java GC создание объектов с новыми почти бесплатными, и они так же легко погружаются в забвение. В C++ выделение памяти (вообще говоря) дорого:
// Sample java code
for (int i = 0; i < 10000000; ++i)
{
String str = new String("hi"); // new is free, GC is almost free for young objects
}
Прямое преобразование в C++ приведет к плохой производительности (использование TR1 shared_ptr в качестве обработчика памяти вместо GC):
for (int i = 0; i < 10000000; ++i)
{
std::shared_ptr<std::string> str(new std::string("hi"));
}
Эквивалентная цикл написана на C++ будет:
for (int i = 0; i < 10000000; ++i)
{
std::string str("hi");
}
Прямой перевод с языка на другой, как правило, заканчивается худший из обоих миров и труднее поддерживать код.
Положительным моментом в этом преобразовании является то, что для переключения с java на C++ (пересечение парадигмы) вам понадобится подходящий объектно-ориентированный дизайн.
Однако некоторые люди говорят, что кодирование C++ не улучшает скорость по сравнению с Java-кодом.
Даже если это сработало, я не уверен, что вы увидите значительное улучшение скорости. Компилятор Jots Java Hotspot JIT стал довольно хорошим.
Вряд ли вероятность того, что этот тип конверсионной оболочки приведет к лучшим результатам. Обычно, когда JVM работает, он преобразует большую часть кода в собственный машинный код. вы предлагаете преобразовать код Jave в C++ и оттуда в собственный машинный код, то есть добавить дополнительную фазу. Однако есть некоторые тривиальные случаи, в которых некоторый выигрыш может быть достигнут из-за того, что:
1) Требуется некоторое время, чтобы загрузить JVM с нуля.
2) Требуется некоторое время, чтобы сделать Jit, когда вы запускаете очень короткую программу, много раз, вы можете предпочесть тратить это время перед запуском.
3) Вы не можете получить одинаковый уровень машинного кода на Java, если вы не работаете в режиме сервера. (В режиме сервера вы ожидаете получить машинный код верхнего уровня, а также тот, который лучше всего подходит для вашего собственного процессора, как обнаружено во время выполнения, чего обычно не хватает на большинстве внедрений C/C++ программ и, кроме того, машинного кода оптимизировано во время выполнения)
Практически невозможно заменить автоматическое управление памятью Java ручным управлением памятью через программу. Таким образом, вы, скорее всего, закончите с программой, которая имеет утечку памяти или код C++, который использует сборщик мусора. Но сборщик мусора в Java имеет гораздо больше возможностей, на которые можно положиться (например, без указателя-арифма, etics), поэтому сборщик мусора на C++, чтобы быть в безопасности, имел пониженную производительность. Таким образом, ваше автоматическое преобразование, скорее всего, снизит производительность.
Вместо этого попробуйте перенести его вручную на C++ или оптимизируйте Java-код.
Вы можете получить языковые системы C++ с сборщиком мусора. –
Да, но, как я уже сказал, C++ - сборщик мусора имеет больше вещей для проверки. Например, стрелка-арифметика усложняет ситуацию. Поэтому C++ - сборщики мусора обычно не так эффективны, как сборщик мусора для генерации Java и .Net. – Mnementh
Использование shared_ptr <>, потому что все будет хитом производительности, а использование консервативного GC, вероятно, будет медленным и позволит некоторые утечки памяти. –
Языки имеют такие разные стили в использовании, что бездумное преобразование было бы малопригодно. Интеллектуальный конвертер будет рядом с возможностью писать, потому что используются разные стили.
Некоторые проблемные области:
- распределение ресурсов контролируется 'попробуйте {} наконец {} блоков в Java в то время как C++ использует RAII.
- Java делает проверку исключений во время выполнения C++.
- Исключения обрабатываются по-разному. Два исключения:
- В Java (последний бросок размноженные)
- В приложении C++ прекращена.
- Java имеет массивную стандартную библиотеку
C++ имеет все ту же функциональность, нужно просто пойти и найти его в Интернете [который является боль]. - Java использует указатели для всего.
- Прямое бездумное преобразование оставит вас с программой, состоящей только из объектов shared_ptr.
Во всяком случае с JIT компиляции Java сравнима с C++ в скорости.
Говоря о таких конвертерах в целом, нельзя ожидать, что они будут содержать либо поддерживаемый, либо высокопроизводительный код, поскольку обычно требуется наличие фактического человека, который понимает язык, на котором написан код. Они очень полезны для облегчения переноса языков. Например, любой язык с конвертером на C может быть быстро реализован на широком спектре языков. Я использовал f2c в середине 90-х, чтобы запустить подпрограмму Fortran на Macintosh.
У вас могут быть или не быть улучшения в производительности, если вы переписываете код на C++. Вероятно, вы столкнетесь с замедлением, если используете автоматический конвертер.
+1. хороший пример – segfault
, так что вы говорите, что люди, которые не знают java или C++, не должны использовать конвертер, потому что его написано людьми, которые не знают java и C++? или что вы не можете исправить его в конвертере, потому что он должен выглядеть точно так же в C++? – IAdapter
@ 01: Насколько я понимаю это сообщение: Написание хорошего конвертера - это не само преобразование, а оптимизация или преобразованный код. Я почти не сомневаюсь, что конвертер вообще выполнит какие-либо оптимизации. Проблема здесь заключается не в том, что люди, которые пишут конвертер, не знают java или C++, но преобразование из собранного мусора языка в не-мусор собрал язык => вы не можете решить без оптимизации и отслеживания использования объектов, если объект должен быть стеком или куча выделена. И таких ловушек гораздо больше, например, java использует 2-байтовые символы по умолчанию, однобайтовые символы C++ ... – ovanes