开放源代码 Delphi泛型库--DGL推荐(Pascal实现的STL)
开放源代码 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;
[解决办法]
关注一下,是怎么写出来的呢?
[解决办法]
mark
[解决办法]
看看
[解决办法]
你的DGL我下来了试用,
在每个函数中缺少文说明,会对推广和应用造成一定困难,Demo演示没有任何(显示信息)结果,不知何故?
[解决办法]
mark
[解决办法]
不错,支持楼主
[解决办法]
kankan
[解决办法]
学习
[解决办法]
还可以吧
[解决办法]
mark
可惜不弄Delphi好多年了
[解决办法]
偶顶
偶喜欢楼主blog中一些优化的东西,楼主能否再来几篇,呵呵。
[解决办法]
不错,友情UP
[解决办法]
图像不懂ing
其实我更想系统的了解一下一些优化的顺序。
比如平常写程序,速度慢了,优化是看看有没IO操作,再看内存(不停的使用new, free),再看算法,再看架构,当然还有一些很关键的函数调用的优化。
但这些只是我一些想法,我是想能看到你在这些方面比较系统的想法,我想楼主比较多经验,能给俺们多写两篇文章,俺就幸福ing。。。嘎嘎。(懒人总是要借口,不去想)
[解决办法]
DGL 就是用了Delphi的变相的宏的实现方法.
[解决办法]
其他实现方法:
1.为每种具体数据类型都制作1个相应的类,优点:速度快,缺点:....
2.使用Variant.优缺点跟1正好相反.
[解决办法]
学习!!!
[解决办法]
Andreas Hausladen写了一个Delphi Language Extensions,其中就包括了Generics支持。
他是通过一个自己写的预处理器实现的。
在这里:http://andy.jgknet.de/dlang
我没有详细比较,不敢说你的实现和他的实现各自的优缺点有哪些。
只是提供一个参考。
[解决办法]
看自己介绍的还是不错的
o(∩_∩)o...
有时间测试一下
[解决办法]
另外去你的博客看了一圈
的确不错
对你的做法表示尊敬 + 崇敬
[解决办法]
你把拨棵 删了 ??~~~ 搞什么啊~~
------解决方案--------------------
看看
[解决办法]
接分
[解决办法]
to housisong (HouSisong) :delphi语法应该不支持范型吧?
[解决办法]
我对C++的STL用得很熟,对delphi,一直用delphi自带的那几个类TList,Tqueue,TStack,TBucketList,THashedStringList,还是第一次听说过DGL,不过我想Delphi不支持template,需要对每种数据类型定义一个类,而且对自定义的record用起来还是没有C++的STL方便吧,什么时候borlanad再对delphi扩充一下语法,让delphi也支持template,那delphi的DGL也可以和C++的STL一样方便了.
[解决办法]
一兩年前我就看到了,但沒有相關 Demo ,不會用。誰能給點 Demo 出來?
[解决办法]
好贴,支持
虽然我不懂,菜鸟一个
但楼主的精神让我佩服
[解决办法]
to housisong(HouSisong) :
对不起
由于对D我了解甚少,而自己最最关心的是C++ STL相关的
所以摘录了你关于这部分的参考数据
当然 我也想知道你是如何测试出来的
如果你觉得我这样做不妥,我可以考虑删除该文
并对此表示深深的歉意
[解决办法]
顶。好东西要大家都知道。
一直都想找这个。
[解决办法]
说一点个人意见啊,
我觉得Delphi的泛型语法最好不要抄C++,
象THashMap <TMyType> 这种描述,
看着胃不舒服。
问题就在于画蛇添足,不兼容基本语法。
完全可以THashMap of TMyType,
何必把 <、> 转义了呢。
[解决办法]
想把vector用在自己写的类上,确老出错....
delphi菜鸟泪奔中....
[解决办法]
收藏,学习