Производительность языков. Объектный Фибоначчи :)

 
1 2 3 4 5
+
-
edit
 

Balancer

администратор
★★★★★
Kernel3> А смысл? Особенно, учитывая то, что множественное наследование как таковое есть не везде.

Нет, мысль правильная. Высокая вложенность наследования (я, понимаю, она имелась в виду, а не множественное наследование, которого, действительно чаще в яыках нет) штука распространённая, например на этом форуме по 4-6 наследований у объектов.

Вернусь в Москву - подумаю о более сложном тесте.
 
US Сергей-4030 #09.08.2008 20:58  @Balancer#02.08.2008 22:06
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Balancer> Jython;493;Jython 2.2.1;jythonc fib;Sun Java 1.6
Balancer> Ruby 1.8;662;ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux];-;ruby 1.8.6
Balancer> JRuby (интерпретация);970;i386-jruby1.0.2;-;i386-jruby1.0.2
Balancer> PHP;1328;PHP 5.2.4-2ubuntu5.2 cli;-;PHP 5.2.4

Гы, я знал, что никто не заморачивается быстродействием. :) Мой интерпретатор после последних изменений вполне можно назвать объектым - при желании. ;) И я вааще ни грамма не задумывался над быстродействием, просто ни на грош. И что? 40-е число Фибоначчи мой интерпретатор вычислил за 358 секунд. Хотя, правда, процессор побыстрее.

code text
  1. {
  2.         function fibo(n) {
  3.                 if(n==0)
  4.                         fibo=0
  5.                 else if(n==1)
  6.                         fibo=1
  7.                 else
  8.                         fibo=fibo(n-1)+fibo(n-2)
  9.         }
  10.        
  11.         n=40;
  12.         begin=time();
  13.         println('Fibo(',n,')=',fibo(n));
  14.         end=time();
  15.         println("Time:",end-begin);
  16. }


Да, я знаю, не выглядит, как объекты, но создается - именно как объекты, для объектов время выполнения было бы то же самое. И - никого не волнует. Это я не в упрек Питону и прочим, это иллюстрация, насколько быстродействие современных языков мало влияет на практическое использование.
 

Murkt

Pythoneer

Существует интерпретатор tinypy, который поддерживает подмножество Питона (с очень неполной динамикой), и работает на порядок быстрее. Но если его начинить такими же возможностями, как и полнофункциональный - тормозить будет дай боже. Так что если бы твой интерпретатор по возможностям приближался к любому из упомянутых - Python, Ruby, или даже PHP, то ты бы с удивлением смотрел на получаемые секунды.
[team Їжачки - сумні падлюки]  
US Сергей-4030 #10.08.2008 01:20  @Murkt#10.08.2008 01:14
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Murkt> Существует интерпретатор tinypy, который поддерживает подмножество Питона (с очень неполной динамикой), и работает на порядок быстрее. Но если его начинить такими же возможностями, как и полнофункциональный - тормозить будет дай боже. Так что если бы твой интерпретатор по возможностям приближался к любому из упомянутых - Python, Ruby, или даже PHP, то ты бы с удивлением смотрел на получаемые секунды.

Не думаю-с. Какие именно возможности ты имеешь в виду? Заметь, в данном случае никаких таких возможностей в тестах не используется - почему же код медленный? Там элементарная последовательность операторов, казалось бы - отлаживай, выполняй. А работает медленно. Нифига ни в каких возможностях тут дело, а именно в том обстоятельстве, что на сверхбыстрое исполнение всем положить.

ЗЫ Насчет "с удивлением" - это не первый проект, над которым я работаю. В моей церковноприходской школе некоторое общее представление о парсерах и генерации кода мне дали. ;)
 
UA Murkt #10.08.2008 11:55  @Сергей-4030#10.08.2008 01:20
+
-
edit
 

Murkt

Pythoneer

Сергей-4030> Не думаю-с. Какие именно возможности ты имеешь в виду? Заметь, в данном случае никаких таких возможностей в тестах не используется - почему же код медленный?
У тебя просто рекурсивная функция. Питон рекурсивную функцию выполняет (на моём ноуте) за 51.61 сек.

Сергей-4030> Там элементарная последовательность операторов, казалось бы - отлаживай, выполняй. А работает медленно. Нифига ни в каких возможностях тут дело, а именно в том обстоятельстве, что на сверхбыстрое исполнение всем положить.
То, что ты не знаешь, что там происходит (и почему оно происходит), не значит, что там ничего не происходит :) (я говорю только про Питон, внутренностей Руби, ПХП, и других я не знаю).

Сергей-4030> ЗЫ Насчет "с удивлением" - это не первый проект, над которым я работаю. В моей церковноприходской школе некоторое общее представление о парсерах и генерации кода мне дали. ;)
Ну-ну. Давай, допили свой интерпретатор до питоноподобных объектов, а потом мы посмотрим, как оно молниеносно будет работать. Можешь и пооптимизировать там всё что угодно. Можешь даже байткод для Джавы нагенерировать.
[team Їжачки - сумні падлюки]  
US Сергей-4030 #10.08.2008 15:50  @Murkt#10.08.2008 11:55
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Сергей-4030>> Там элементарная последовательность операторов, казалось бы - отлаживай, выполняй. А работает медленно. Нифига ни в каких возможностях тут дело, а именно в том обстоятельстве, что на сверхбыстрое исполнение всем положить.
Murkt> То, что ты не знаешь, что там происходит (и почему оно происходит), не значит, что там ничего не происходит :) (я говорю только про Питон, внутренностей Руби, ПХП, и других я не знаю).

Как минимум, я знаю, что там НЕ происходит проверка того, что код не использует никаких специальных возможностей и следующая за тем оптимизация исполнения этого кода. Это ведь можно сделать в любом случае, правильно? Сделано это? Нет. Почему? Потому, что быстродействие не так важно.
 
UA Murkt #10.08.2008 18:12  @Сергей-4030#10.08.2008 15:50
+
-
edit
 

Murkt

Pythoneer

Murkt>> То, что ты не знаешь, что там происходит (и почему оно происходит), не значит, что там ничего не происходит :) (я говорю только про Питон, внутренностей Руби, ПХП, и других я не знаю).
Сергей-4030> Как минимум, я знаю, что там НЕ происходит проверка того, что код не использует никаких специальных возможностей и следующая за тем оптимизация исполнения этого кода. Это ведь можно сделать в любом случае, правильно? Сделано это? Нет. Почему? Потому, что быстродействие не так важно.
Не повторяй ошибки Реконструктора. Да, там не происходит проверка того, что код не использует никаких специальных возможностей. Почему? Потому что он их использует.
[team Їжачки - сумні падлюки]  
US Сергей-4030 #10.08.2008 19:37  @Murkt#10.08.2008 18:12
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Murkt>>> То, что ты не знаешь, что там происходит (и почему оно происходит), не значит, что там ничего не происходит :) (я говорю только про Питон, внутренностей Руби, ПХП, и других я не знаю).
Сергей-4030>> Как минимум, я знаю, что там НЕ происходит проверка того, что код не использует никаких специальных возможностей и следующая за тем оптимизация исполнения этого кода. Это ведь можно сделать в любом случае, правильно? Сделано это? Нет. Почему? Потому, что быстродействие не так важно.
Murkt> Не повторяй ошибки Реконструктора. Да, там не происходит проверка того, что код не использует никаких специальных возможностей. Почему? Потому что он их использует.

Нет, в конкретно этом случае - не использует. То есть если быстродействие было очень важно, можно было проверить, какие возможности использует конкретно данный участок кода и гонять его в специально настроенном режиме. Я не понимаю, как тут можно возражать. Если у вас система наворочена до небес, но программа вычисляет 2+2, то можно проанализировать код, понять, что большинство фич не нужно и исполнить максимально быстро. Это если быстродействие суперважно. А если не важно - то можно и забить. Как и делают. Поскольку на самом деле не важно.
 
UA Murkt #10.08.2008 19:54  @Сергей-4030#10.08.2008 19:37
+
-
edit
 

Murkt

Pythoneer

Murkt>> Не повторяй ошибки Реконструктора. Да, там не происходит проверка того, что код не использует никаких специальных возможностей. Почему? Потому что он их использует.
Сергей-4030> Нет, в конкретно этом случае - не использует. То есть если быстродействие было очень важно, можно было проверить, какие возможности использует конкретно данный участок кода и гонять его в специально настроенном режиме. Я не понимаю, как тут можно возражать. Если у вас система наворочена до небес, но программа вычисляет 2+2, то можно проанализировать код, понять, что большинство фич не нужно и исполнить максимально быстро. Это если быстродействие суперважно. А если не важно - то можно и забить. Как и делают. Поскольку на самом деле не важно.
При рекурсии практически не использует. При "объектной рекурсии" - использует. В реальных программах таких участков вида "2+2", которые как-то там можно было бы оптимизировать анализом кода почти нет. Поэтому, с анализом кода очень часто всё работало бы медленнее (на анализ ведь тоже время нужно). Если быстродействие действительно очень важно (то есть, какой-то "математический" код), то эта часть просто выносится в нативный код (напрямую в Си, или всякими Cython, Boost.python, pyrex - неважно).

А добавлять анализатор кода для того, чтоб Сергей-4030 посмотрел и сказал "Даа, хоть и толку нет - но ведь заботятся о быстродействии!" никому не нужно.
[team Їжачки - сумні падлюки]  
US Сергей-4030 #10.08.2008 20:01  @Murkt#10.08.2008 19:54
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Murkt> При рекурсии практически не использует. При "объектной рекурсии" - использует. В реальных программах таких участков вида "2+2", которые как-то там можно было бы оптимизировать анализом кода почти нет. Поэтому, с анализом кода очень часто всё работало бы медленнее (на анализ ведь тоже время нужно). Если быстродействие действительно очень важно (то есть, какой-то "математический" код), то эта часть просто выносится в нативный код (напрямую в Си, или всякими Cython, Boost.python, pyrex - неважно).
Murkt> А добавлять анализатор кода для того, чтоб Сергей-4030 посмотрел и сказал "Даа, хоть и толку нет - но ведь заботятся о быстродействии!" никому не нужно.

Че-то я не понял, о чем ты споришь тогда. Очевидно, что быстродействие - не важно. И я то же говорю.
 
+
-
edit
 

Sova777

новичок
Я не силён в создании package'ей, но, по-моему, код должен выглядеть так

fib.pm:
code perl
  1. package fib;
  2. BEGIN{}
  3.  
  4. sub new
  5. {
  6.  my $self={};
  7.  bless($self);
  8.  $self->{_value}=shift;
  9.  return $self;
  10. }
  11.  
  12. sub value
  13. {
  14.   my $self = shift;
  15.   $_value = $self->{_value};
  16.   if($_value <= 2) {
  17.     return 1;
  18.   }
  19.   my $f1=fib->new($_value - 1);
  20.   my $f2=fib->new($_value - 2);
  21.  
  22.   return $f1->value() + $f2->value();
  23. }
  24.  
  25. END{}

fib.pl:
code perl
  1. #!/usr/bin/perl
  2.  
  3. use fib;
  4.  
  5. my $fib=fib->new(40);
  6. print $fib->value();
 
UA Murkt #11.08.2008 01:46  @Сергей-4030#10.08.2008 20:01
+
-
edit
 

Murkt

Pythoneer

Сергей-4030> Че-то я не понял, о чем ты споришь тогда. Очевидно, что быстродействие - не важно. И я то же говорю.
Я говорю, что попробуй написать код, заботясь о быстродействии, и чтоб он работал хотя бы с той же скоростью, с какой работает тот код, который написан "без отвлечения внимания" на быстродействие.
[team Їжачки - сумні падлюки]  
US Сергей-4030 #11.08.2008 04:31  @Murkt#11.08.2008 01:46
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Сергей-4030>> Че-то я не понял, о чем ты споришь тогда. Очевидно, что быстродействие - не важно. И я то же говорю.
Murkt> Я говорю, что попробуй написать код, заботясь о быстродействии, и чтоб он работал хотя бы с той же скоростью, с какой работает тот код, который написан "без отвлечения внимания" на быстродействие.

По-моему, данное высказывание имеет внутреннее противоречие. Но лень спорить. ;)
 

shild

новичок
Хм, решил запустить тесты на виндовом хосте и померять результаты в нём. Немного изменил методику тестирования - во всех тестах расчёт числа производится 5 раз (в цикле for, примерно как для явы в текущем варианте), каждый тест запускается по 3 раза. Для подсчёта времени используется команда measure-command из powershell.

Получилось примерно следующее (данные можно сказать "сырые"):

C++ Stack
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
/MD /O2

TotalSeconds      : 1,6775173
TotalMilliseconds : 1677,5173

TotalSeconds      : 1,5985777
TotalMilliseconds : 1598,5777

TotalSeconds      : 1,6121065
TotalMilliseconds : 1612,1065

Java 1.6
javac 1.6.0_07

TotalSeconds      : 25,5596054
TotalMilliseconds : 25559,6054

TotalSeconds      : 26,4356922
TotalMilliseconds : 26435,6922

TotalSeconds      : 25,747172
TotalMilliseconds : 25747,172

Scala
Scala compiler version 2.7.1.final — Copyright 2002-2008, LAMP/EPFL

TotalSeconds      : 24,5937402
TotalMilliseconds : 24593,7402

TotalSeconds      : 25,0129865
TotalMilliseconds : 25012,9865

TotalSeconds      : 24,7166078
TotalMilliseconds : 24716,6078

Nemerle
Nemerle Compiler (ncc) version 0.9.4 (SVN)

TotalSeconds      : 20,1507993
TotalMilliseconds : 20150,7993

TotalSeconds      : 19,3857878
TotalMilliseconds : 19385,7878

TotalSeconds      : 19,934683
TotalMilliseconds : 19934,683

Nemerle (pmatch)
Nemerle Compiler (ncc) version 0.9.4 (SVN)

TotalSeconds      : 20,7255444
TotalMilliseconds : 20725,5444

TotalSeconds      : 21,0457136
TotalMilliseconds : 21045,7136

TotalSeconds      : 20,691166
TotalMilliseconds : 20691,166

Boo
Boo Compiler version 0.8.2.2960 (CLR v2.0.50727.3053)

TotalSeconds      : 33,562377
TotalMilliseconds : 33562,377

TotalSeconds      : 33,6250741
TotalMilliseconds : 33625,0741

TotalSeconds      : 33,6302801
TotalMilliseconds : 33630,2801

C#
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1

TotalSeconds      : 20,8085315
TotalMilliseconds : 20808,5315

TotalSeconds      : 20,0362258
TotalMilliseconds : 20036,2258

TotalSeconds      : 20,1337748
TotalMilliseconds : 20133,7748

C++ Heap (????)
TotalMinutes      : 3,38703320666667
TotalSeconds      : 203,2219924
TotalMilliseconds : 203221,9924

Непонятна ужасающая производительность плюсовой версии с хипом, поэтому я её временно исключил из тестирования. Остальное вроде бы укладывается в ранее проведённые измерения, с тем только отличием что CLR от JVM практически не отстаёт.

Надеюсь в тестах я не накосячил :)
 6.06.0
+
-
edit
 

Balancer

администратор
★★★★★
shild> Непонятна ужасающая производительность плюсовой версии с хипом

Угу. А опции компиляции какие? Регистровые аргументы использовал?

shild> с тем только отличием что CLR от JVM практически не отстаёт.

Ну, это, вроде, итак было известно, что JIT в виндовом CLR отличный.
 
+
-
edit
 

shild

новичок
Balancer> Угу. А опции компиляции какие? Регистровые аргументы использовал?

cl /MD /O2

не очень понял, что есть суть регистровые аргументы.

Balancer> Ну, это, вроде, итак было известно, что JIT в виндовом CLR отличный.

дак вроде и все результаты этого теста тоже были достаточно предсказуемы :) Потому как на таком простом тесте весь код должен быть примерно одинаковым.

Кстати провёл ещё некоторые эксперименты:

1. Виндовая JVM по всей видимости медленнее её линуксового варианта, поскольку соотношение с программой на Си у неё хуже (либо лучше компилятор Си, что маловероятно с учётом разницы в 300%):

3,9 / 0,66 = 5,9
25559,6054 / 1598,5777 = 15,9

Видимо это связано с тем, что под винду у меня только "клиентский" вариант JVM. Потом запущу на этой же машине под линуксом и проверю.

2. При замене class на struct в программах под CLR получаем прирост производительности

Nemerle
Nemerle Compiler (ncc) version 0.9.4 (SVN)

TotalSeconds : 10,7305699
TotalMilliseconds : 10730,5699

TotalSeconds : 10,6986734
TotalMilliseconds : 10698,6734

TotalSeconds : 11,1083176
TotalMilliseconds : 11108,3176

Nemerle (pmatch)
Nemerle Compiler (ncc) version 0.9.4 (SVN)

TotalSeconds : 12,4860128
TotalMilliseconds : 12486,0128

TotalSeconds : 12,0789566
TotalMilliseconds : 12078,9566

TotalSeconds : 12,0265097
TotalMilliseconds : 12026,5097

Boo
Boo Compiler version 0.8.2.2960 (CLR v2.0.50727.3053)
TotalSeconds : 22,7728378
TotalMilliseconds : 22772,8378

TotalSeconds : 22,8289095
TotalMilliseconds : 22828,9095

TotalSeconds : 22,8361498
TotalMilliseconds : 22836,1498

C#
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1

TotalSeconds : 11,463037
TotalMilliseconds : 11463,037

TotalSeconds : 11,5494111
TotalMilliseconds : 11549,4111

TotalSeconds : 11,4963924
TotalMilliseconds : 11496,3924


3. Не пойму причину отставания Boo. Сейчас буду разбираться. Может там 6 раз вычисления идут, а не 5. Потому что не должен он отставать.

Проверил - посмотрел генерёный IL и выяснил, что Boo все внутренние арифметические операции выполняет с числами как с Int64, поэтому навтыкал везде код вида:
code cil
  1.     IL_001b:  ldfld      uint32 Fib::_value
  2.     IL_0020:  conv.ovf.i8
  3.     IL_0021:  ldc.i4.1
  4.     IL_0022:  conv.ovf.i8
  5.     IL_0023:  sub.ovf
  6.     IL_0024:  conv.ovf.i4

Если все преобразования удалить и собрать ilasmом, то производительность становится такой же как и у C#.

PS: почему в тэге code не отображаются первые 4 пробела ?

4. Думаю что сравнивать компиляторы под одну платформу (JVM/CLR) на такой простой задаче не очень правильно, т.к. байт-код должен быть практически один в один. Думаю нужно поюзать фичи, предоставляемые компилятором и сравнить их производительность.

PS: не удержался и написал немного другой вариант на Nemerle (совсем не подходящий под условие задачи, но показывающий некоторые стандартные возможности макросов):
code nemerle
  1. using System;
  2. using Nemerle;
  3.  
  4. public struct Fib
  5. {
  6.     private _value : int;
  7.  
  8.     public this(n : int) { _value = n }
  9.  
  10.     [Memoize]
  11.     private getValue(cur : int) : int
  12.     {
  13.       | 0
  14.       | 1
  15.       | 2 => 1
  16.       | _ => getValue(cur - 1) + getValue(cur - 2);
  17.     }
  18.  
  19.     public value() : int
  20.     {
  21.       getValue(_value);
  22.     }
  23.  
  24.     public static Main() : void
  25.     {
  26.         for(mutable i=0; i<45; i++)
  27.         {
  28.             Console.WriteLine(Fib(i).value())
  29.         }
  30.     }
  31. }


Время выполнения:
Nemerle (Memoize): TotalMilliseconds : 78,9371
Nemerle (без Memoize): TotalMilliseconds : 44677,2631
C++: TotalMilliseconds : 38509,5169

Код на С++:
code cpp
  1.  
  2. #include <stdio.h>
  3.  
  4. class Fib
  5. {
  6.   private:
  7.      int _value;
  8.  
  9.   public:
  10.     Fib(int n) { _value = n; }
  11.  
  12.     int getValue(int cur)
  13.     {
  14.         if (cur <= 2)
  15.             return 1;
  16.  
  17.         return getValue(cur - 1) + getValue(cur - 2);
  18.     }
  19.  
  20.     int value()
  21.     {
  22.         return getValue(_value);
  23.     }
  24. };
  25.  
  26. int main()
  27. {
  28.     for(int i=0; i<45; i++)
  29.     {
  30.         Fib x = Fib(i);
  31.         printf("n=%dn", x.value());
  32.     }
  33.     return 0;
  34. }
 6.06.0
Это сообщение редактировалось 12.11.2008 в 11:03

shild

новичок
Да, и ещё, забыл. Как можно посмотреть код, генерёный JITом ? Можно конечно сдампить процесс и ковыряться там в поисках нужного отрывка, но может есть способ проще ?
 6.06.0
+
-
edit
 

Balancer

администратор
★★★★★
shild> cl /MD /O2
shild> не очень понял, что есть суть регистровые аргументы.

/Gr добавь (если память не изменила за несколько лет простоя :))

Тогда методы, где можно, будут вызываться с помещением аргументов не в стек, а в регистры, где их хватает. У GCC с /O2 это уже автоматически включено.

Можно по ассемблерному листингу убедиться.

shild> 1. Виндовая JVM по всей видимости медленнее её линуксового варианта, поскольку соотношение с программой на Си у неё хуже

Вполне может быть, что в этом одна из причин того, что под виндой не удалось повторить мой опыт с Я не верю своим глазам! Java быстрее, чем C++???

во, кстати, там и опции компиляции приведены: cl /Ox /O2 /Fa /FAsc /G6 /Gr

shild> PS: почему в тэге code не отображаются первые 4 пробела ?

Старая фича. Он, как и другие подобные тэги, выкидывает пробельные символы в начале и конце блока. Надобудет поправить...

Всё, вроде выкинул там trim() :)
 
+
-
edit
 

Balancer

администратор
★★★★★
shild> Да, и ещё, забыл. Как можно посмотреть код, генерёный JITом ?

Не в курсе, никогда не видел.
 
+
-
edit
 

shild

новичок
Balancer> во, кстати, там и опции компиляции приведены: cl /Ox /O2 /Fa /FAsc /G6 /Gr

не помогло, сейчас может дизассемблер найду - поковыряю чего он там накомпилировал такого тормозного.
 6.06.0
+
-
edit
 

Balancer

администратор
★★★★★
Balancer>> во, кстати, там и опции компиляции приведены: cl /Ox /O2 /Fa /FAsc /G6 /Gr
shild> не помогло, сейчас может дизассемблер найду - поковыряю чего он там накомпилировал такого тормозного.

так там опция есть, аналог gcc-шного -S, генерация листинга ассемблерного. Только на память не помню, что за опция.
 
+
-
edit
 

tarasv

опытный

Balancer>>> во, кстати, там и опции компиляции приведены: cl /Ox /O2 /Fa /FAsc /G6 /Gr
shild>> не помогло, сейчас может дизассемблер найду - поковыряю чего он там накомпилировал такого тормозного.
Balancer> так там опция есть, аналог gcc-шного -S, генерация листинга ассемблерного. Только на память не помню, что за опция.

/FAsc и есть генерация ассемблерного листинга по полной программе - с процессорным кодом и исходниками. Если поставить /FAs то будет исходник плюс ассемблер без машкодов.
 7.07.0

shild

новичок
Balancer>> так там опция есть, аналог gcc-шного -S, генерация листинга ассемблерного. Только на память не помню, что за опция.
tarasv> /FAsc и есть генерация ассемблерного листинга по полной программе - с процессорным кодом и исходниками. Если поставить /FAs то будет исходник плюс ассемблер без машкодов.

да я уж поглядел и даже ответ написал, только вот почему-то на форуме он не сохранился... ну может я "Посмотреть" нажал и забыл "Отправить".

Стэк:
code 6502acme
  1. ; 15   :
  2. ; 16   :         Fib f1 = Fib(_value - 1);
  3.  
  4.   00013 8d 48 ff         lea     ecx, DWORD PTR [eax-1]
  5.   00016 89 4c 24 04      mov     DWORD PTR _f1$[esp+8], ecx
  6.  
  7. ; 17   :         Fib f2 = Fib(_value - 2);
  8.  
  9.   0001a 83 c0 fe         add     eax, -2                        ; fffffffeH
  10.   0001d 56               push    esi


Хип:
code 6502acme
  1.  
  2. ; 16   :         Fib *f1 = new Fib(_value - 1);
  3.  
  4.   00012 6a 04            push    4
  5.   00014 e8 00 00 00 00   call    ??2@YAPAXI@Z           ; operator new
  6.   00019 83 c4 04         add     esp, 4
  7.   0001c 85 c0            test    eax, eax
  8.   0001e 74 09            je      SHORT $LN4@value
  9.   00020 8b 0e            mov     ecx, DWORD PTR [esi]
  10.   00022 49               dec     ecx
  11.   00023 89 08            mov     DWORD PTR [eax], ecx
  12.   00025 8b f8            mov     edi, eax
  13.   00027 eb 02            jmp     SHORT $LN5@value
  14. $LN4@value:
  15.   00029 33 ff            xor     edi, edi
  16. $LN5@value:
  17.  
  18. ; 17   :         Fib *f2 = new Fib(_value - 2);
  19.  
  20.   0002b 6a 04            push    4
  21.   0002d e8 00 00 00 00   call    ??2@YAPAXI@Z           ; operator new
  22.   00032 83 c4 04         add     esp, 4
  23.   00035 85 c0            test    eax, eax
  24.   00037 74 0b            je      SHORT $LN6@value
  25.   00039 8b 16            mov     edx, DWORD PTR [esi]
  26.   0003b 83 ea 02         sub     edx, 2
  27.   0003e 89 10            mov     DWORD PTR [eax], edx
  28.   00040 8b f0            mov     esi, eax
  29.   00042 eb 02            jmp     SHORT $LN7@value
  30. $LN6@value:
  31.   00044 33 f6            xor     esi, esi


видимо такая тормозная реализация new/delete. Наверное там какой-нить отладочный вариант включен, который проверяет целостность хипа по верхней/нижней границе при освобождении памяти.
 6.06.0
+
-
edit
 

Balancer

администратор
★★★★★
Ткнули на ошибку: Новости - OpenSource - Вышел Rails 2.2

Балансеру на заметку: c psyco косяк вышел.
надо так:

from psyco.classes import _metaclass_

class Fib:
...

будет раз в 5-6 быстрее.
 


В прежних условиях тест повторить не могу (конфигурация машины поменялась), а на другой (ну и чтобы по 5 минут не ждать, с меньшим, 33-м числом) получается так:

Python w/o psyco user 0m18.782s
Python w psyco user 0m2.432s


Итого - 7,7 раза ускорение.

Тест на пропорциональнсть, 35-е число:

Python w/o psyco user 0m48.745s
Python w psyco user 0m6.527s


7,5 раза.

В общем, можно предположить, что в изначальном тесте 40-е число было бы посчитано за 41-42 секунды. Вношу правку с примечанием :)
 
RU RomanMak #24.11.2008 11:51  @Balancer#02.08.2008 22:11
+
-
edit
 

RomanMak

новичок
Balancer> Java:
Кто ж так на Джаве пишет! :-) Создавать без всякой необходимости пару объектов за один вызов int value()!?
Попробуйте запустить бенчмарки хотя бы с таким кодом:

code java5
  1. public class Fib
  2. {
  3.     private final int _value;
  4.     private final int _fib;
  5.  
  6. public Fib(int n)   {
  7.     _value = n;
  8.     _fib = calculateFib(n);
  9. }
  10.  
  11. public int getValue() {
  12.     return _value;
  13. }
  14.  
  15. public int getFib() {
  16.     return _fib;
  17. }
  18.  
  19. private static int calculateFib(int n) {
  20.    if(n <= 2)
  21.        return 1;
  22.  
  23.    int f1 = calculateFib(n - 1);
  24.    int f2 = calculateFib(n - 2);
  25.  
  26.    return f1 + f2;
  27. }
  28.  
  29. public static void main(String[] argv)
  30. {
  31.     for(int i=0; i<10; i++)
  32.    {
  33.       Fib x = new Fib(40);
  34.       System.out.println(x.getFib());
  35.    }
  36. }
  37. }
 7.07.0
1 2 3 4 5

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru