开放源代码 Delphi泛型库--DGL推荐(Pascal实现的STL)

housisong 2007-06-16 10:51:10
开放源代码 Delphi泛型库--DGL推荐(Pascal实现的STL)
(第二次开贴推荐 希望DGL能成为你手边的利器!)

Delphi中的容器和算法实在太缺乏了,又存在很多不一致,使用也很不方便。在构造一些容器和算法的时候,总是怀念C++的泛型和STL;2004年的时候个人尝试在Delphi中编写泛型代码,所以就有了DGL(The Delphi Generic Library);简单来说DGL就是在Delphi中部分实现了STL;
DGL库能够以类型安全的方式支持基本类型、指针、Interface、结构(record)、Object结构(Delphi中已经不推荐使用)、类成员函数指针、类(class)的值语义(Delphi中不习惯使用类的值语义,所以不建议使用)等其它用户自定义类型,并且类型安全,容易使用,容易扩展;
DGL的框架来自STL,包括组织方式、命名规则、算法复杂度规格等(包括"陷阱":),实际实现性能和最有名的SGI的STL实现性能接近;

我使用这个库三年了,用它构造的程序已经有上百万人在使用:)
代码支持Delphi7、TurboDelphi、Delphi2007、FreePascal编译环境(其他环境没有测试过)

DGL的下载地址: http://cosoft.org.cn/projects/dgl/
DGL的更多相关信息(实现原理、与各种库的性能对比、简单的Demo实例等等)可以参看我的blog: http://blog.csdn.net/housisong/category/152693.aspx

摘录部分于STL库的性能对比数据:
DGL lib (Turbo Delphi2006 Compile)========================================================
Container: PushBack Next Visite Random Visite Insert At Middle PushFront
TVector 0.029 us 0.007 us 0.079 us 27600.000 us 66800.000 us
TDeque 0.007 us 0.009 us 0.234 us 113200.000 us 0.006 us
TList 0.029 us 0.015 us 8520.000 us 0.066 us 0.037 us

IVector 0.025 us 0.015 us 0.107 us 33000.000 us 79600.000 us
IDeque 0.010 us 0.015 us 0.245 us 103400.000 us 0.013 us
IList 0.050 us 0.017 us 8950.000 us 0.054 us 0.034 us

Container: Insert Find Next Visite
Map 0.370 us 3.592 us 0.075 us
MultiMap 0.388 us 3.873 us 0.104 us
Set 0.366 us 3.254 us 0.062 us
MultiSet 0.345 us 3.275 us 0.062 us

HashMap 0.292 us 0.832 us 0.039 us
HashMultiMap 0.275 us 0.898 us 0.060 us
HashSet 0.248 us 0.847 us 0.043 us
HashMultiSet 0.245 us 0.847 us 0.036 us
================================================================================

STL (VC6 Compile)===============================================================
Container: PushBack Next Visite Random Visite Insert At Middle PushFront
vector 0.041 us 0.005 us 0.078 us 31200 us 68800 us
deque 0.013 us 0.006 us 0.227 us 365600 us 0.012 us
list 0.169 us 0.022 us 21800 us 0.180 us 0.183 us

Container: Insert Find Next Visite
map 0.431 us 3.174 us 0.048 us
set 0.433 us 3.174 us 0.049 us
multimap 0.430 us 3.174 us 0.047 us
multiset 0.427 us 3.174 us 0.048 us
STL (VC2005 Compile)===============================================================
vector 0.019 us 0.009 us 0.078 us 62600 us 140600 us
deque 0.067 us 0.013 us 0.227 us 168800 us 0.061 us
list 0.269 us 0.017 us 15600 us 0.277 us 0.269 us

Container: Insert Find Next Visite
map 2.436 us 4.813 us 0.042 us
set 2.473 us 4.813 us 0.041 us
multimap 2.420 us 4.813 us 0.041 us
multiset 2.416 us 4.813 us 0.041 us

hash_map 0.888 us 1.501 us 0.207 us
hash_set 1.378 us 1.453 us 0.207 us
hash_multimap 1.373 us 1.450 us 0.207 us
hash_multiset 1.380 us 1.450 us 0.207 us

(SGI)STL (DEV-C++4.98 GCC max optimize Compile)=================================
Container: PushBack Next Visite Random Visite Insert At Middle PushFront
vector 0.016 us 0.005 us 0.070 us 34400 us 62400 us
deque 0.011 us 0.009 us 0.258 us 865600 us 0.013 us
list 0.047 us 0.014 us 9400 us 0.052 us 0.036 us

Container: Insert Find Next Visite
map 0.538 us 3.226 us 0.033 us
set 0.516 us 3.226 us 0.034 us
multimap 0.492 us 3.174 us 0.038 us
multiset 0.495 us 3.994 us 0.039 us

hash_map 0.145 us 0.701 us 0.043 us
hash_set 0.234 us 0.650 us 0.044 us
hash_multimap 0.639 us 0.698 us 0.044 us
hash_multiset 0.138 us 0.650 us 0.043 us
================================================================================

摘录部分使用Demo:
//Demo uses IIntVector ---------------------------------------------------------
procedure TFormDGLDemo.btn_IIntVectorClick(Sender: TObject);
var
intVector : IIntVector; //interface type ; Vector use as delphi's array;
i,Sum : integer;
begin
intVector :=TIntVector.Create;

for i:=0 to 100-1 do
intVector.PushBack(i);
Assert(intVector.Size()=100);

Sum:=0;
for i:=0 to intVector.Size()-1 do
Sum:=Sum+intVector.Items[i];
Assert(Sum=(0+99)*100 div 2);

// intVector is interface type not need free;
end;


//Demo uses TIntVector ---------------------------------------------------------
procedure TFormDGLDemo.btn_TIntVectorClick(Sender: TObject);
var
intVector : TIntVector; //class type
i,Sum : integer;
begin
intVector :=TIntVector.Create;
try
for i:=0 to 100-1 do
intVector.PushBack(i);
Assert(intVector.Size()=100);

Sum:=0;
for i:=0 to intVector.Size()-1 do
Sum:=Sum+intVector.Items[i];
Assert(Sum=(0+99)*100 div 2);

finally
intVector.Free; //intVector is class type;
//use class type is maybe faster than interface type;
//recommend priority use DGL container as interface by most time;
end;

end;


//Demo uses IIntDeque ----------------------------------------------------------
procedure TFormDGLDemo.btn_IIntDequeClick(Sender: TObject);
var
intDeque : IIntDeque;
i,Sum : integer;
begin
intDeque :=TIntDeque.Create;

for i:=0 to 100-1 do
intDeque.PushBack(i);
Assert(intDeque.Back()=99);Assert(intDeque.Front()=0);
Assert(intDeque.Size()=100);

for i:=0 to 100-1 do
intDeque.PushFront(i); //Deque's PushFront and PushBack is the same fast;
Assert(intDeque.Back()=99);Assert(intDeque.Front()=99);
Assert(intDeque.Size()=200);

Sum:=0;
for i:=0 to intDeque.Size()-1 do
Sum:=Sum+intDeque.Items[i];
Assert(Sum=((0+99)*100 div 2)*2);
end;

//Demo uses IPointerSet --------------------------------------------------------
procedure TFormDGLDemo.btn_IPointerSetClick(Sender: TObject);
var
piSet : IPointerSet;
it : IPointerIterator;
i,Sum : integer;
begin
piSet :=TPointerHashSet.Create;

for i:=0 to 200-1 do
piSet.Insert(Pointer(i div 2)); //values is [0,1,..99]
Assert(piSet.size()=100);

Sum:=0;
it:=piSet.ItBegin;
for i:=0 to piSet.Size-1 do
begin
inc(Sum,integer(it.Value));
it.Next;
end;
Assert(Sum=((0+99)*100 div 2));

for i:=0 to 100-1 do
begin
it:=piSet.Find(Pointer(i));
Assert(not it.IsEqual(piSet.ItEnd));
Assert(it.Value=Pointer(i));
end;

for i:=0 to 100-1 do
piSet.EraseValue(Pointer(i)); //== piSet.Erase(piSet.Find(Pointer(i)));
Assert(piSet.IsEmpty());
Assert(piSet.Size()=0);

end;
...全文
2093 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
housisong 2008-01-09
  • 打赏
  • 举报
回复
to: boythl
是我写的啊 我的库简称DGL (The Delphi Generic Library) ;
网上也有一个库叫DGL(Delphi OpenGL),这个不是我写的
jarraytan 2008-01-09
  • 打赏
  • 举报
回复
楼主大虾,DGL是你写的是吗?
woaichenyu 2007-07-29
  • 打赏
  • 举报
回复
收藏,学习
Amphetamine 2007-07-27
  • 打赏
  • 举报
回复
想把vector用在自己写的类上,确老出错....
delphi菜鸟泪奔中....
  • 打赏
  • 举报
回复
说一点个人意见啊,
我觉得Delphi的泛型语法最好不要抄C++,
象THashMap<TMyType>这种描述,
看着胃不舒服。
问题就在于画蛇添足,不兼容基本语法。
完全可以THashMap of TMyType,
何必把<、>转义了呢。
hawk_e2e 2007-07-23
  • 打赏
  • 举报
回复
顶。好东西要大家都知道。
一直都想找这个。
liuin 2007-07-23
  • 打赏
  • 举报
回复
好贴,支持
虽然我不懂,菜鸟一个
但楼主的精神让我佩服
huzhangyou 2007-07-23
  • 打赏
  • 举报
回复
to housisong(HouSisong) :
对不起
由于对D我了解甚少,而自己最最关心的是C++ STL相关的
所以摘录了你关于这部分的参考数据

当然 我也想知道你是如何测试出来的

如果你觉得我这样做不妥,我可以考虑删除该文
并对此表示深深的歉意
housisong 2007-07-21
  • 打赏
  • 举报
回复
to: fox1999(红狐)
我的blog上就有使用DGL的Demo啊
fox1999 2007-07-21
  • 打赏
  • 举报
回复
一兩年前我就看到了,但沒有相關 Demo ,不會用。誰能給點 Demo 出來?
housisong 2007-07-16
  • 打赏
  • 举报
回复
to: superyys(无血野人)
虽然没有tempalte的语法支持,但DGL确实做到了泛型,使用的是一种自动宏代码展开的方案; 所以,不同的类型不需要单独写代码,所有的类型共用相同的源代码基础;DGL也支持record自定义结构;
当然,用户使用起来可能没有STL方便,因为DGL在模板类型具现化的时候需要手工写(为了降低使用难度,常见数据类型的具现化工作库已经预置了);
superyys 2007-07-16
  • 打赏
  • 举报
回复
我对C++的STL用得很熟,对delphi,一直用delphi自带的那几个类TList,Tqueue,TStack,TBucketList,THashedStringList,还是第一次听说过DGL,不过我想Delphi不支持template,需要对每种数据类型定义一个类,而且对自定义的record用起来还是没有C++的STL方便吧,什么时候borlanad再对delphi扩充一下语法,让delphi也支持template,那delphi的DGL也可以和C++的STL一样方便了.
superyys 2007-07-16
  • 打赏
  • 举报
回复
to housisong (HouSisong) :delphi语法应该不支持范型吧?
logne 2007-07-12
  • 打赏
  • 举报
回复
接分
housisong 2007-07-11
  • 打赏
  • 举报
回复
to: hangzhou_hammer
没看明白你说什么:(
yuanguangxing 2007-07-11
  • 打赏
  • 举报
回复
看看
hangzhou_hammer 2007-07-11
  • 打赏
  • 举报
回复
你把拨棵 删了 ??~~~ 搞什么啊~~
housisong 2007-07-09
  • 打赏
  • 举报
回复
to:huzhangyou
你转载文章也要尽量保持文章的完整性吧(那篇各个库的容器性能对比文章),我写的也不容易啊,你就把我最重要的部分去掉了:(
huzhangyou 2007-07-08
  • 打赏
  • 举报
回复
另外去你的博客看了一圈
的确不错

对你的做法表示尊敬 + 崇敬
huzhangyou 2007-07-08
  • 打赏
  • 举报
回复
看自己介绍的还是不错的
o(∩_∩)o...
有时间测试一下
加载更多回复(24)

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧