Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2008.11.09;
Скачать: [xml.tar.bz2];

Вниз

Новые языковые возможности. Первые попытки...   Найти похожие ветки 

 
MBo ©   (2008-09-15 16:03) [0]

Пробую дженерики.
На примере линейного поиска в массиве. Глобальную параметризованную функцию создать компилятор не дает, так что делаю метод формы (можно сделать фиктивный объект с классовым методом, чтобы его не создавать)
Сравниваю по скорости сермяжный поиск, поиск с использованием функции сравнения, дефолтный интерфейс сравнения дженериков, и анонимную функцию сравнения.

uses
 ... Generics.Defaults

type
 TEqualFunc<T> = reference to function(X, Y: T): Boolean;
 TEqual = function(X, Y: Integer): Boolean;

 TForm3 = class(TForm)...
   function FindFirstValueSimple(const A: array of Integer; const Value: Integer): Integer;
   function FindFirstValueCompareFunc(const A: array of Integer; const Value: Integer; Equal: TEqual): Integer;
   function FindFirstValueComparer<T>(const A: array of T; const Value: T): Integer;
   function FindFirstValueAnonFunc<T>(const A: array of T; const Value: T; const Equal: TEqualFunc<T>): Integer;
 end;

var
 Form3: TForm3;

implementation

{$R *.dfm}

function UserTime: Int64;
var
 CreationT,ExitT,KernelT, UserT : _FILETIME;
begin
 GetProcessTimes(GetCurrentProcess, CreationT, ExitT,KernelT, UserT);
 Result := Int64(UserT) div 10000;
end;

function TForm3.FindFirstValueAnonFunc<T>(const A: array of T; const Value: T;
 const Equal: TEqualFunc<T>): Integer;
var
 i: Integer;
begin
 Result := -1;
 for i:= 0 to High(A) do
   if Equal(A[i], Value) then
     Exit(i);
end;

function TForm3.FindFirstValueCompareFunc(const A: array of Integer;
 const Value: Integer; Equal: TEqual): Integer;
var
 i: Integer;
begin
 Result := -1;
 for i:= 0 to High(A) do
   if Equal(A[i], Value) then
     Exit(i);
end;

function TForm3.FindFirstValueComparer<T>(const A: array of T; const Value: T): Integer;
var
 i: Integer;
begin
 Result := -1;
 for i:= 0 to High(A) do
   if TComparer<T>.Default.Compare(A[i], Value) = 0 then
     Exit(i);
end;

function TForm3.FindFirstValueSimple(const A: array of Integer;
 const Value: Integer): Integer;
var
 i: Integer;
begin
 Result := -1;
 for i:= 0 to High(A) do
   if A[i] = Value then
     Exit(i);
end;

function IntEqual(X, Y: Integer): Boolean;
begin
 Result := X = Y
end;

procedure TForm3.Button1Click(Sender: TObject);
var
 i, k, N: Integer;
 A: array of Integer;
 t0, t1, t2, t3, t4: Int64;
begin
 Randomize;
 N := 100000000;
 SetLength(A, N);
 for i := 0 to N - 1 do
   A[i] := Random(N);
 t0 := UserTime;
 k := FindFirstValueSimple(A, 1000);
 t1 := UserTime;
 k := FindFirstValueCompareFunc(A, 1000, IntEqual);
 t2 := UserTime;
 k := FindFirstValueComparer<Integer>(A, 1000);
 t3 := UserTime;
 k := FindFirstValueAnonFunc<Integer>(A, 1000, function(X, Y: Integer): Boolean begin Result := X = Y end);
 t4 := UserTime;
 Memo1.Lines.Add(Format("Indx: %d  Simple: %d  CompFunc: %d  GenComparer: %d  GenAnonFunc: %d",[k, t1-t0, t2-t1, t3-t2, t4 - t3]));
end;

end.


Indx: -1  // элемент не найден, макс. количество сравнений
Simple: 250
CompFunc: 500
GenComparer: 5109
GenAnonFunc: 625


 
MBo ©   (2008-09-15 16:07) [1]

При использовании анонимной функции - скорость вполне сравнима с работой процедуры с обычной глобальной функцией сравнения. В данном случае, когда почти ничего не делается, кроме этих самых сравнений, накладные расходы на вызов функций сравнения, конечно, велики.
Однако TComparer<T>.Default.Compare - ну ооочень медленно работает...


 
Tricky_   (2008-09-15 16:32) [2]

Кто нибудь бы знающий написал бы статью. Про нововведения. Его бы очень и очень много людей благодарило!
Особено про различие delphi 7 и 2009 - т.к. скоро много людей будет переходить с (5, 6) 7 на 2009.
2005-2007 многие не юзали, судя по форумам статьям, исходникам, - хватало и семерки.


 
Riply ©   (2008-09-15 16:42) [3]

Правда, у меня еще нет Delphi 2009 (эт временно),
но я присоединяюсь к пожеланию [2] Tricky_


 
Sapersky   (2008-09-15 16:53) [4]

Однако TComparer<T>.Default.Compare - ну ооочень медленно работает...

Здесь уже обсуждали:
http://delphimaster.net/view/15-1219512329/

Самое смешное, что сравнение на базе TypeInfo можно реализовать в Delphi... ну когда TypeInfo появилось - думаю, в D2. Хотя и без "гламурных" <T>, конечно.


 
KilkennyCat ©   (2008-09-15 17:15) [5]

А вот я наоборот, с 2007 ушел обратно на 7.
Но все равно, интересно...


 
pasha_golub ©   (2008-09-16 10:13) [6]

Так эта... если я буду использовать TList<T> , то метод IndexOf будет работать в 10 раз медленней, чем он работал в TList.IndexOf? Все верно?


 
MBo ©   (2008-09-16 10:33) [7]

>pasha_golub
для TList<Integer> у меня IndexOf получилось в 5 раз медленнее.
Заполнение  списка - незначительно медленнее.


 
_REA_   (2008-09-16 15:38) [8]

А почему? Разница то вроде только в синтаксисе...


 
pasha_golub ©   (2008-09-16 17:11) [9]


> MBo ©   (16.09.08 10:33) [7]


> для TList<Integer> у меня IndexOf получилось в 5 раз медленнее.

Однако, это очень и очень удручает.


 
MBo ©   (2008-09-16 17:28) [10]

>Разница то вроде только в синтаксисе
при использовании поиска с дженериками сравнение идет не напрямую, а вызывается функция сравнения, неявно использующая информацию о типе, подобно тому, как сделано в первом посте в FindFirstValueComparer. И вызов этот довольно хитрый и длинный(толком всю цепочку я не отследил, дебаг с дженериками глючит порой). Получается, что накладные расходы на этот синтаксический сахар довольно велики, что хреново с точки зрения высокопроизводительных контейнерных классов, да и писанины дополнительной для того, чтобы заставить дженерики работать, тоже немало. Эх, не шаблоны это, совсем не шаблоны...


 
jack128_   (2008-09-16 18:17) [11]


> Эх, не шаблоны это, совсем не шаблоны...

а это и не шаблоны. Это дженерики.


 
Sapersky   (2008-09-16 18:32) [12]

И вызов этот довольно хитрый и длинный(толком всю цепочку я не отследил, дебаг с дженериками глючит порой)

На глаз, по выложенному Generics.Defaults, для integer:
TComparer<T>.Default -> _LookupVtableInfo -> Comparer_Selector_Binary -> Compare_U4 (как TComparer.Default.Compare). Плюс ещё, вероятно, компилятор добавляет некоторое кол-во Addref/Release для всех интерфейсов, даже если там просто заглушки, как в случае Comparer"ов.

Чего я не понял - так это делается ли для обход вложенных типов, т.е. будут ли корректно сравниваться длинные строки в записях и т.п. Пока никакого обхода не вижу, вроде бы для tkRecord в _LookupVtableInfo просто вызывается Comparer_Selector_Binary и потом (для общего случая) Compare_Binary -> BinaryCompare.

Если не сложно - проверьте, сравните что-нибудь такое:
TMyRec = record
 Name : String;
 Value : Integer;
end;
Var v1, v2 : TMyRec;
v1.Name := "aaa";
v2.Name := "aa"; v2.Name := v2.Name + "a";
// указатели v1.Name и v2.Name разные, но строка одинаковая
// т.е. простой CompareMem даст неверный результат



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2008.11.09;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.007 c
2-1222712909
serjo
2008-09-29 22:28
2008.11.09
Сворачивающаяся панель


2-1222699729
<Evil>
2008-09-29 18:48
2008.11.09
Как скрыть колонку в DBGrid ?


2-1222779966
cruiser
2008-09-30 17:06
2008.11.09
Ловим сообщения программы


2-1222762898
neon-w
2008-09-30 12:21
2008.11.09
NAN????


4-1199910118
=BuckLr=
2008-01-09 23:21
2008.11.09
Bidi mode средствами API





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский