On-line: Andrey, PSP, гостей 1. Всего: 3 [подробнее..]
АвторСообщение
Администратор




Пост N: 2208
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 23.12.11 13:43. Заголовок: Интерпретаторы


Возьмем 3 продукта: 1с 8, visual foxpro и harbour.
Назначение у них различное, коня и трепетную лань сравнивать не стоит, но есть и кое-что общее: все они имеют интерпретатор, построенный на похожем принципе: сначала делается предкомпиляция в некий промежуточный код, а затем этот код выполняется.
Поэтому возникла мысль сравнить производительность этих интерпретаторов, посмотреть, так сказать, чей движок мощнее.

Берем простенький тест:

func main
Local i, nLoops := 5000000
Local L_F := 112345.67
Local L_N := 10000
Local L_C := "0123456789ABCDEF"
Local nn, nf, cc
Local nn1 := 0
Local nf1 := 0.1
Local cc1 := ""
Local nn2, nf2

Local nSec := Seconds()

for i := 1 to nLoops
nn := L_N
nf := L_F
cc := L_C
nn := L_N + 1
nf := L_F + 1.0
cc := L_C + L_C
nn1 += L_N + 1
nf1 += L_F + 1.0
if (nn1 % 2) == 0
// cc1 += L_C + chr(nn1 % 256)
endif
if (len(cc1) % 3) == 0
nn2 := nn1 % 13
nf2 := nf1 % 13
endif
nn := (nn1 + L_N + 1)*100/15
nf := (nf1 + L_F + 1.0)*100.00/15.00
next
? Seconds() - nSec
? nn, nf, cc
? nn1, nf1, len(cc1)
? nn2, nf2
retu nil

И запускаем его, с учетом различия в синтаксисе языков, конечно.
Компьютер: Celeron 2.5 GHZ, 1GB RAM

Закомментаренный оператор - это конкатенация строк. Сразу скажу, что с конкатенацией не справился никто, кроме, естественно, харбора.
Да и на его результате конкатенация сказалась незначительно:
Время с конкатенацией 18.59 сек
Время без конкатенации 16.86 сек

foexpro показал вполне приличный результат - 48.08 сек, что всего лишь в три раза хуже харбора.

Ну а что же хваленые канадские профессионалы 1с ? Ждать пришлось долго, 330 сек, что в 20(!) раз хуже харбора.
Здесь даже не подходит аналогия сравнения двигателя Запорожца с двигателем Ламборджини, надо сравнивать с двигателем реактивного истребителя.
Как говорится, за много-много лет ничто не мешало 1с обзавестись приличным движком, да вот как-то не сложилось.
Ну а движок харбора порадовал, хорош.
Можно было протестировать продукты и на других режимах, скажем, добавить тест ООП, но, думается, смысла в этом нет, класс уже понятен и без этого.


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 33 , стр: 1 2 All [только новые]





Пост N: 350
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 26.12.11 21:08. Заголовок: Pasha пишет: Прогна..


Pasha пишет:

 цитата:
Прогнал свой тест на java

можно исходник адаптированный для java?

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2242
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 26.12.11 21:08. Заголовок: Pasha пишет: Прогна..


Pasha пишет:

 цитата:
Прогнал свой тест на java


Пробни еще Perl , думаю он будет еще быстрее.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2217
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 26.12.11 21:12. Заголовок: AlexMyr пишет: можн..


AlexMyr пишет:

 цитата:
можно исходник адаптированный для java?



Да, конечно. Конкатенацию строк я опять убрал, java с ней не справляется.

package javaapplication1;

public class JavaApplication1 {

public static void main(String[] args) {

int i;
int nLoops = 5000000;
double L_F = 112345.67;
int L_N = 10000;
String L_C = "0123456789ABCDEF";
long nn;
double nf;
String cc;
long nn1 = 0;
double nf1 = 0.1;
String cc1 = "";
long nn2;
double nf2;

for( i = 1; i <= nLoops; i++ )
{
nn = L_N;
nf = L_F;
cc = L_C;
nn = L_N + 1;
nf = L_F + 1.0;
cc = L_C + L_C;
nn1 += L_N + 1;
nf1 += L_F + 1.0;
if( (nn1 % 2) == 0 )
{
// cc1 += L_C + "0";
//+ nn1.toString(256);
}
if( (cc1.length() % 3) == 0 )
{
nn2 = nn1 % 13;
nf2 = nf1 % 13;
}
nn = (nn1 + L_N + 1)*100/15;
nf = (nf1 + L_F + 1.0)*100.00/15.00;
}
System.out.println("Hello");
System.out.println(nn1);
System.out.println(nf1);
}
}


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2218
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 26.12.11 21:16. Заголовок: Еще пару слов о фокс..


Еще пару слов о фокспро. За примерно 10 лет от vfp6 до vfp9sp2 его движок потерял в "мощности" примерно 10%.
Тест конечно очень условный, я его набросал на скорую руку, просто для того, чтобы выстроить продукты по рангу.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 351
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 26.12.11 21:18. Заголовок: Pasha пишет: Да, ко..


Pasha пишет:

 цитата:
Да, конечно. Конкатенацию строк я опять убрал, java с ней не справляется.

спасибо, попробую.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 352
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 27.12.11 00:09. Заголовок: На домашнем ноуте та..


На домашнем ноуте такой результат:

java:
пришлось поправить первые строки
package javaapplication1;

public
class JavaApplication1 {

public static void main(String[] args) {


Hello
50005000000
5.61733349977449E11

harbour:
14.60

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1051
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 27.12.11 00:28. Заголовок: AlexMyr пишет: harb..


AlexMyr пишет:

 цитата:
harbour:
14.60


Для java добавьте в код

long nBegin = System.currentTimeMillis(), nEnd;
..
nEnd = System.currentTimeMillis();
System.out.println( (nEnd - nBegin) / 1000.0 );



Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1052
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 03.01.12 00:20. Заголовок: Не знаю почему, но м..


Не знаю почему, но мне понравилась идея сравнения Java c Harbour, нет не вообще (тут все понятно - масштабы конечно не те), а именно выполнения конкретного кода.
Для начала я скачал и установил Java SE 7u2 (JDK 7) и чуть поправил код от Pasha
/*jtest.java*/ 

import static java.lang.System.out;

public class jtest {
public static void main(String[] args) {
final int nLoops = 5000000;
final double L_F = 112345.67;
final int L_N = 10000;
final String L_C = "0123456789ABCDEF";
String cc = "";
long nn = 0;
double nf = 0.0;
long nn1 = 0;
double nf1 = 0.1;
StringBuilder cc1 = new StringBuilder(65536);
long nn2 = 0;
double nf2 = 0.0;
long tB;

out.printf("%s %s %s %s %s\n", System.getProperty("java.vm.vendor"),
System.getProperty("java.vm.name"),
System.getProperty("java.version"),
System.getProperty("os.name"),
System.getProperty("os.arch"));

tB = System.currentTimeMillis();

for( int i = 1; i <= nLoops; i++ ) {
nn = L_N;
nf = L_F;
cc = L_C;
nn = L_N + 1;
nf = L_F + 1.0;
cc = L_C + L_C;
nn1 += L_N + 1;
nf1 += L_F + 1.0;

if( nn1 % 2 == 0 ) {
cc1.append(L_C).append( (char) (nn1 % 256) );
}

if( cc1.length() % 3 == 0 ) {
nn2 = nn1 % 13;
nf2 = nf1 % 13;
}

nn = (nn1 + L_N + 1) * 100/15;
nf = (nf1 + L_F + 1.0) * 100.00/15.00;

if( i % 1000000 == 0 ) {
out.printf("%d\n", nLoops-i);
}
}
out.println("");
out.printf("%.2f\n", (System.currentTimeMillis() - tB) / 1000.0);
out.printf("%d\n", nLoops);
out.println("");
out.printf("%d %.3f %s\n", nn, nf, cc);
out.printf("%d %.3f %d\n", nn1, nf1, cc1.length());
out.printf("%d %.6f\n", nn2, nf2);
}
}
А затем с помощью скрипта (будете копировать - помните о концевых пробелах, да и начальных - тоже)
rem jtest.bat 
@ECHO OFF
IF NOT DEFINED "%JDK_HOME%" SET JDK_HOME="C:\Program Files\Java\jdk1.7.0_02"

@%JDK_HOME%\bin\javac -Xlint jtest.java
@%JDK_HOME%\bin\jar -vcfe apptest.jar jtest jtest.class
@%JDK_HOME%\bin\jar -i apptest.jar

@%JDK_HOME%\bin\java -Xint -Xincgc -Xms512m -Xmx512m -jar apptest.jar
запустил его на исполнение.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1053
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 03.01.12 00:40. Заголовок: Получил такой вот ре..


Получил такой вот результат
Oracle Corporation Java HotSpot(TM) Client VM 1.7.0_02 Windows XP x86 

8,63
5000000

333366733340 3744889748827,460 0123456789ABCDEF0123456789ABCDEF
50005000000 561733349977,449 42500000
3 6,778931

Немного о параметрах запуска
-Xint - Java HotSpot VM работает в режиме интерпретатора (байт кода), режим не основной - отключает JIT и прочие фирменные ухищрения Sun
-Xincgc - включить инкрементальный сборщик мусора
-Xms512m -Xmx512m - установить начальный и максимальный размер кучи памяти равным 512 Mb (у Java апетит на память хороший ).

Если -Xint упустить или использовать -Xmixed, результат будет другой
Oracle Corporation Java HotSpot(TM) Client VM 1.7.0_02 Windows XP x86 

1,73
5000000

333366733340 3744889748827,460 0123456789ABCDEF0123456789ABCDEF
50005000000 561733349977,449 42500000
3 6,778931




Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1054
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 03.01.12 00:43. Заголовок: Теперь перейдем к Ha..


Теперь перейдем к Harbour. Выполнялся вот такой код от Pasha
 
#translate printf( [<explist,...>] ) => QOut( hb_strFormat(<explist>) )
#translate println( [<explist,...>] ) => QOut( <explist> )

#define N_LOOPS 5000000
#define L_F 112345.67
#define L_N 10000
#define L_C "0123456789ABCDEF"

FUNCTION main()
LOCAL cc
LOCAL nn
LOCAL nf
LOCAL nn1 := 0
LOCAL nf1 := 0.1
LOCAL cc1 := ""
LOCAL nn2
LOCAL nf2
LOCAL tB
LOCAL i

QQOut( hb_Version(), hb_Version(11), hb_Version(1), hb_Version(21) )

tb := hb_SecondsCPU()

FOR i := 1 to N_LOOPS
nn := L_N
nf := L_F
cc := L_C
nn := L_N + 1
nf := L_F + 1.0
cc := L_C + L_C
nn1 += L_N + 1
nf1 += L_F + 1.0

IF nn1 % 2 == 0
cc1 += L_C + chr(nn1 % 256)
END

IF Len(cc1) % 3 == 0
nn2 := nn1 % 13
nf2 := nf1 % 13
END

nn := (nn1 + L_N + 1) * 100/15
nf := (nf1 + L_F + 1.0) * 100.00/15.00

IF i % 1000000 == 0
printf( "%d", N_LOOPS - i )
END
NEXT

println()
printf("%.2f", hb_SecondsCPU() - tb)
printf("%d", N_LOOPS)
println()
printf("%d %.3f %s", nn, nf, cc)
printf("%d %.3f %d", nn1, nf1, Len(cc1))
printf("%d %.6f", nn2, nf2)

RETURN NIL


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1055
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 03.01.12 00:58. Заголовок: Harbour был собран д..


Harbour был собран для компилятора MinGW 4.6.1 и VC 16 (из состава MSVC 2010) (HB_USER_CFLAGS=-DHB_GC_AUTO)
В принципе по результатам выполнения speedtst, всегда лучшим был VC. Но после выхода MinGW 4.6.x разницой в 0.25 - 1 сек можно принебречь.
Компилируем hbmk2 jtest.prg -st и запускаем. Получаем такой вот результат
Harbour 3.1.0dev (Rev. 17173) Jan  2 2012 18:44:16 MinGW GNU C 4.6.1 (32-bit) WIN 

13.16
5000000

333366733340 3744889748827.460 0123456789ABCDEF0123456789ABCDEF
50005000000 561733349977.449 42500000
3 6.778931

Harbour 3.1.0dev (Rev. 17173) Jan 2 2012 18:12:19 Microsoft Visual C++ 16.0.30319 (32-bit)
WIN

15.30
5000000

333366733340 3744889748827.460 0123456789ABCDEF0123456789ABCDEF
50005000000 561733349977.449 42500000
3 6.778931
Т.е. получается Java HotSpot(TM) где-то в 1,5-1,7 раза быстрее в режиме интерпретатора байт-кода.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1056
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 03.01.12 01:13. Заголовок: Теперь компилируем h..


Теперь компилируем hbmk2 jtest.prg -st /gc3 и снова запускаем. Смотрим результат
Harbour 3.1.0dev (Rev. 17173) Jan  2 2012 18:44:16 MinGW GNU C 4.6.1 (32-bit) WIN 

7.22
5000000

333366733340 3744889748827.460 0123456789ABCDEF0123456789ABCDEF
50005000000 561733349977.449 42500000
3 6.778931

Harbour 3.1.0dev (Rev. 17173) Jan 2 2012 18:12:19 Microsoft Visual C++ 16.0.30319 (32-bit)
WIN

9.50
5000000

333366733340 3744889748827.460 0123456789ABCDEF0123456789ABCDEF
50005000000 561733349977.449 42500000
3 6.778931

Все таки есть у HotSpot(TM) свои фишки - 4,1-5,5
Заметили, MinGW быстрее?
Что-то я расписался здесь, но ведь флейм же
Кстати, тестировалось на машине с процессором AMD Athlon X2 64 Dual 3600+ (2,01 ГГц), ОЗУ 1 Гб DDR2.


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2219
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 03.01.12 09:18. Заголовок: Про JIT я тоже сразу..


Про JIT я тоже сразу сообразил, что такое сравнение с харбором не совсем корректно, но как отключить его не увидел
Я пользовался netbeans. и jre6 от sun, а там такого ключика не увидел.
Получается, как интерпретаторы java и harbour находятся примерно на одном уровне, а в режиме реального кода java все-таки намного быстрее.

Резервы у harbour конечно еще есть. Я думаю, в режиме -gc3 надо исключать работу со стеком. Частично это уже сделано, это т.н. multi PCODE operations.
Я попробовал в таком же духе изменить операцию вида
Field->FName := uLocalVar
Такой тест:

Local nLoops := 5000000
Local nVar1 := 1
Local nVar1 := 2
Local nVar1 := 3
Local nVar1 := 4
for i := 1 to nLoops
Field->F1 := nVar1
Field->F1 := nVar2
Field->F1 := nVar3
Field->F1 := nVar4
next

показал увеличение производительности примерно на 5%

Можно было бы оптимизировать в таком же духе все команды HB_P_JUMP* после операций сравнения:

Вместо

if( hb_xvmGreater() ) break;
if( hb_xvmPopLogical( &fValue ) ) break;
if( !fValue )
goto lab00001;

Компилировать код в

if( hb_xvmNewGreater( &fValue ) ) break;
if( !fValue )
goto lab00001;

и так далее

Но у Przemeka в todo list есть такой пункт:

% rewrite compiler internal logic to not generate PCODE online
but use some meta code (expression list) and introduce new multiline
optimizations using above meta code.

Наверное, это какое-то радикальное решение.

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 33 , стр: 1 2 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 202
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет