Архив метки: скорость

Delphi vs Java

Привлекает меня разработка под платформу Android. Как известно, основной язык программирования под нее — Java. Можно, конечно, использовать NDK (C C++) но в моем случае в этом нет никакой необходимости. Заодно появилась возможность поизучать Java. Кстати, минута рекламы — если есть желание изучать, крайне рекомендую купить книгу Якова Фаина «Java Programming, 24-Hour Trainer». Книга написано максимально сжато, но как по мне объясняет многое. Из замеченных недостатков — достаточно сухое, академическое изложение, но для меня оно cамое то, так как до этого много писал на Delphi и C#, рюшечки не нужны. Если хотите с рюшечками — «Head first Java». Да, не забудьте заглянуть в errata книги Якова, есть несколько достаточно важных опечаток.

Минута рекламы закончилась. Изучаю Java, в общем. Все пишут, что Java — тормоз. Виртуальная машина, проверки, сборка мусора когда не надо, все дела. Куда, в общем, с такой мордой в наш ряд. Ну пока сам не проверишь — не поверишь, дело такое. Нашел в интернете интересный примерчик, набросал его на Java и Delphi XE2. Delphi — 32 бита, все оптимизации включены, все поверки отключены. 

Итак, код Java:

import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
 
public class Main {
    private static double func(double x){
        double y = x*x;
        return y;
    }
    public static void main(String[] args) throws IOException {
        double vp=50000, np=0, snp=np, step=0.0001, sum=0;
        DateFormat df = DateFormat.getDateTimeInstance();
        
        System.out.println("Integral calculations...");
        Date cnt1 = new Date();
        while (np+step < vp) {
            sum = sum + (func(np) + func(np+step)) / 2*step;
        	//sum = sum + (np*np + (np+step)*(np+step)) / 2*step;
            np = np + step;
        }
        Date cnt2 = new Date();
        System.out.println("Integral from " + snp + " to " + vp + " step "+ step +" is equal " + sum);
        System.out.println("Begin time: "+df.format(cnt1));
        System.out.println("End time: " + df.format(cnt2));
        System.out.println("Difference: "+(cnt2.getTime()-cnt1.getTime())/1000 + " seconds");
        
    }
}

Как видите, ничего военного. В цикле вызывается простейшая функция. Для проверки написан расчет «на месте» без вызова (сейчас закомментирован) Теперь то же самое на Delphi:

program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

function itg (x : Double) : Double;
begin
  Result := x*x;
end;

var
  vp, np, snp, step,sum : Double;
  cnt1, cnt2, cnt3 : TDateTime;
begin
  vp := 50000;
  np := 0;
  snp := np;
  step := 0.0001;
  sum := 0;
  Writeln('Integral calculations...');
  cnt1 := Now();
  while (np + step < vp) do begin
    sum := sum + (itg(np) + itg(np + step)) / 2*step;
    //sum := sum + ((np*np + (np + step)*(np + step))) / 2 * step;
    np := np + step;
  end;
  cnt2 := Now();
  cnt3 := cnt2 - cnt1;
  Writeln('Integral from ' + FloatToStr(snp) + ' to ' + FloatToStr (vp) +
                    ' step ' + FloatToStr(step) + ' is equal ' + FloatToStr(sum)+ #13 +
                    'Begin time: ' + FormatDateTime('hh:mm:ss',cnt1) + #13 +
                    'End time: ' +  FormatDateTime('hh:mm:ss',cnt2)+ #13+
                    'Difference: ' + FormatDateTime('ss', cnt3) + ' seconds');



end.

Вся логика абсолютно такая же. Предвкушаю безусловную победу нативного кода. Мало того что нативный — Embarcadero триста раз говорила, что они круто оптимизировали компилятор.

Барабанная дробь — смотрим результаты.

Delphi:

 

WTF? Вариант с вызовом функции отрабатывает в 4 раза медленнее чем инлайн — 13 секунд! И это простейшая функция, подставлять подобное компиляторы научились уже 100 лет назад. Даже не хочется писать на C#, подставит — 100%. Про С++ молчу.

Ладно, посмотрим на результаты «тормозной» джавы:

У меня комментариев по поводу тормознутости в расчетах нет. Чистая математика — 1 секунда. Причем в обоих вариантах, Java умеет делать то, что не умеет Delphi. 

Я охотно поверю, что у Java могут быть другие затыки. Еще больше поверю, что 90% затыков — кривые руки программистов. Не раз видел в C# использование String вместо StringBuilder, к примеру.

Java порадовала. Есть желание накатать небольшую програмку для чтения бинарого файла (это по работе), цифровой его фильтрации и отображении на экране. Если дело пойдет хорошо — можно писать кроссплатформенные приложения. Для задач со строгими временными рамками я от С++ или Delphi никуда не уйду, что делать. Но не только же это пишем 🙂

В Java пока огорчает GUI — она изначально была создана для другого. Найти пока красоты не могу для гуев, но особо и не искал. Вот, намалевал на Java морду к калькулятору для изучения вопроса — честный копипаст с майкрософта 🙂

Иду по книге Якова. Заодно у него есть (были) курсы по Java, как теперь — не знаю. Язык интересный, нравится. Непонятно пока только, как писать без парамеров методов by ref. Делать все через приватные члены классов муторно. Пожелайте мне удачи 🙂