fastCSharp 1.6 内存数据库引擎及代码生成实例 发布

showjim 2014-01-31 02:01:39
加精
如果你的服务器有大量空闲内存,会不会有一种可耻的感觉呢?如果内存不够大,应该花点钱买买这种感觉。
大内存相比于硬盘,不仅仅是程序跑得更快,更重要的是有效利用大内存能让程序开发更快捷。长期来说,节省的开发人工成本,相比于内存价格还是很划算的。
看看现在市面上出现了各种各样的内存数据库,忍不住凑了个热闹。花了几天时间写了个可嵌入的内存数据库物理引擎,以及代码生成实例。codeplex连不上,连续提交3个小时了,只好上传到了51nod。

1.支持嵌入模式,也就是可以不需要服务端,直接本地函数调用。
2.支持代码生成模式与反射模式,反射模式序列化性能相比于代码生成模式可能相差4倍以上。
3.序列化现在支持二进制与JSON两种模式。因为二进制序列化不能识别成员变化,只能用于稳定的类型定义,所以暂时采用JSON序列化弥补,以后有时间在增加一个专用的序列化程序。代码生成模式中JSON序列化性能相比于二进制序列化可能相差2倍以上,序列化生成的数据量也可能相差3倍以上。

以往的代码生成实例一样,采用自定义属性配置环境参数,比如
        [fastCSharp.setup.cSharp.memoryDatabase(CacheType = typeof(fastCSharp.memoryDatabase.cache.identityArray<,>), FileName = null, MinRefreshSize = 1, MaxLogCacheSize = 0, ClientPoolType = typeof(clientPool), IsEmbed = false, IsJsonSerialize = false)]
对于代码生成模式,数据库操作代理就是 Model.memoryDatabase.Default,比如
            private static memoryDatabase db = memoryDatabase.Default;
对于反射模式,数据库操作代理需要自己创建。嵌入模式与远程模式的数据库代理分别如下
            private static fastCSharp.setup.cSharp.memoryDatabase.localTable<identity, int> db = fastCSharp.setup.cSharp.memoryDatabase.table.Open(new setup.cSharp.memoryDatabase.localTable<identity, int>(new fastCSharp.memoryDatabase.cache.identityArray<identity>()));
            private static fastCSharp.setup.cSharp.memoryDatabase.remoteTable<identity, int> db = fastCSharp.setup.cSharp.memoryDatabase.table.Open(new setup.cSharp.memoryDatabase.remoteTable<identity, int>(new clientPool(), new fastCSharp.memoryDatabase.cache.identityArray<identity>()));
性能测试,采用的数据定义如下
        public abstract class data
{
public bool Bool;
public byte Byte;
public sbyte SByte;
public short Short;
public ushort UShort;
public int Int;
public uint UInt;
public long Long;
public ulong ULong;
public DateTime DateTime;
public float Float;
public double Double;
public decimal Decimal;
public Guid Guid;
public char Char;
public string String;
public bool? BoolNull;
public byte? ByteNull;
public sbyte? SByteNull;
public short? ShortNull;
public ushort? UShortNull;
public int? IntNull;
public uint? UIntNull;
public long? LongNull;
public ulong? ULongNull;
public DateTime? DateTimeNull;
public float? FloatNull;
public double? DoubleNull;
public decimal? DecimalNull;
public Guid? GuidNull;
public char? CharNull;
}
当成员String为null的时候,二进制序列化数据大概120+字节,Unicode编码的JSON序列化数据大概580+字节。
嵌入模式 与 远程模式+缓存模式[缓存模式相当于批量处理] 采用10W对象数据为单位做写入测试,远程模式采用1W对象数据为单位做写入测试。数据库操作代理采用单线程循环模式进行单机测试,测试机 Inter(R) Celeron(R) M CPU 520 1.60GHz,测试耗时包括 物理层处理 + 网络通讯处理 + 客户端对象创建与序列化处理。
代码生成模式(要求性能的选择)测试结果
本地模式二进制序列化:10W对象,序列化数据 12M+,平均耗时0.62s,CPU 100%(嵌入式的稳定类型选择)
远程缓存二进制序列化:10W对象,序列化数据 12M+,平均耗时 0.8s,CPU 100%(可靠性要求低的稳定类型选择)
远程模式二进制序列化: 1W对象,序列化数据1.2M+,平均耗时 0.8s,CPU 100%(要求可靠的稳定类型选择)
本地模式 JSON 序列化:10W对象,序列化数据 58M+,平均耗时 2s,CPU<100%[我的硬盘跟不上了](嵌入式的非稳定类型选择)
远程缓存 JSON 序列化:10W对象,序列化数据 58M+,平均耗时2.45s,CPU 100%(可靠性要求低的非稳定类型选择)
远程模式 JSON 序列化: 1W对象,序列化数据5.8M+,平均耗时1.05s,CPU 100%(要求可靠的非稳定类型选择)

反射模式(讨厌代码生成的选择)测试结果
本地模式二进制序列化:10W对象,序列化数据 12M+,平均耗时3.05s,CPU 100%
远程缓存二进制序列化:10W对象,序列化数据 12M+,平均耗时 3.2s,CPU 100%
远程模式二进制序列化: 1W对象,序列化数据1.2M+,平均耗时 1.2s,CPU 100%
本地模式 JSON 序列化:10W对象,序列化数据 58M+,平均耗时 4.6s,CPU 100%
远程缓存 JSON 序列化:10W对象,序列化数据 58M+,平均耗时 5s,CPU 100%
远程模式 JSON 序列化: 1W对象,序列化数据5.8M+,平均耗时1.35s,CPU 100%


后续有两个优化方向:一是抛弃JSON序列化,改为专用的能识别成员的二进制序列化;二是远程模式抛弃可靠度较低的缓存模式,客户端在通讯层实现异步数据集中处理机制,也就是自动合并异步请求批量处理应对高并发处理。
...全文
554 点赞 收藏 16
写回复
16 条回复
showjim 2014年02月21日
如果出现程序集映像错误,说明ui的.NET框架版本太低(默认是.NET2.0)。需要把fastCSharp与ui项目目标框架版本重新设置,至少重新编译两次(直到不出现log.txt提示之后在编译一次)。
回复 点赞
showjim 2014年02月21日
引用 14 楼 kiba518 的回复:
下载下来了 但是运行ui 安装总是失败 不知道怎么弄 555
直接运行的ui是我的个人工具。 如果不使用代码生成模式只需要引用fastCSharp.dll就可以了。 如果使用代码生成模式,需要在项目的编译事件中调用带参数的ui,可以参考testCase项目,比如我这里写的是相对路径,你可以根据实际情况修改为绝对路径
if exist $(ProjectDir)..\ui\bin\Release\fastCSharp.ui.exe $(ProjectDir)..\ui\bin\Release\fastCSharp.ui.exe $(ProjectName) $(ProjectDir) $(TargetPath) $(TargetName)
回复 点赞
智商余额不足 2014年02月20日
回复 点赞
kiba518 2014年02月20日
下载下来了 但是运行ui 安装总是失败 不知道怎么弄 555
回复 点赞
kiba518 2014年02月20日
撸主 我如何能下载到这个框架呢 我想学习下
回复 点赞
qq10086q 2014年02月20日
大牛
回复 点赞
beyondcj 2014年02月19日
回复 点赞
ohfiner 2014年02月16日
回复 点赞
showjim 2014年02月16日
引用 7 楼 sp1234 的回复:
序列化模式,对一个分布式部署产品的整个生命过程影响重大。当你改变服务器端的class定义的属性(或者简单地改变Assembly版本号)的时候,json可以持续工作,而二进制的方式立刻就崩溃了。
成员识别二进制序列化,就是为了解决这个问题的,用于替代JSON。序列化数据如下
[memberIndex:int][length:int][data]...[END]
,每当class定义修改以后,会将定义成员信息[memberIndex+Type+Name]也提交到数据库,客户端可以自动识别memberIndex转换到正确的memberIndex。
回复 点赞
以专业开发人员为伍 2014年02月16日
序列化模式,对一个分布式部署产品的整个生命过程影响重大。当你改变服务器端的class定义的属性(或者简单地改变Assembly版本号)的时候,json可以持续工作,而二进制的方式立刻就崩溃了。
回复 点赞
showjim 2014年02月16日
1.最新版本已经抛弃JSON序列化,改为能识别成员的二进制序列化。 2.最新版本客户端在通讯层实现了并发请求合并处理,但是与旧版本的缓存模式还有一定的差距。因为暂时客户端还没有提供异步支持,同步等待锁有一定的消耗。 测试依然采用10W对象数据为单位做写入测试,对于远程模式分别测试了客户端单线程与多线程并发。远程模式客户端发送数据缓冲区设置为 16KB。 测试机 Inter(R) Celeron(R) M CPU 520 1.60GHz,测试耗时包括 物理层处理 + 网络通讯处理 + 客户端对象创建与序列化处理 + 简单的缓存同步更新操作。 当成员String为null的时候,普通二进制序列化数据大概120+字节,成员识别二进制序列化数据大概350+字节。 代码生成模式+普通二进制序列化 [10W对象 + 序列化数据12M]测试结果
本地模式  1线程:平均耗时  0.6s,CPU 100%
远程模式  1线程:平均耗时 4.75s,CPU 100%
远程模式  2线程:平均耗时 3.11s,CPU 100%
远程模式  5线程:平均耗时 1.95s,CPU 100%
远程模式 10线程:平均耗时 1.62s,CPU 100%
远程模式 20线程:平均耗时 1.45s,CPU 100%
远程模式 25线程:平均耗时 1.44s,CPU 100%
远程模式 40线程:平均耗时 1.42s,CPU 100%
远程模式 50线程:平均耗时 1.43s,CPU 100%
远程模式 80线程:平均耗时 1.67s,CPU 100%
远程模式200线程:平均耗时  2.1s,CPU 100%
远程模式500线程:平均耗时 2.54s,CPU 100%
代码生成模式+成员识别二进制序列化 [10W对象 + 序列化数据35M]测试结果
本地模式  1线程:平均耗时 0.96s,CPU 100%
远程模式  1线程:平均耗时  5.4s,CPU 100%
远程模式  2线程:平均耗时  3.8s,CPU 100%
远程模式  5线程:平均耗时 2.66s,CPU 100%
远程模式 10线程:平均耗时 2.35s,CPU 100%
远程模式 20线程:平均耗时 2.07s,CPU 100%
远程模式 25线程:平均耗时 2.22s,CPU 100%
远程模式 40线程:平均耗时 2.23s,CPU 100%
远程模式 50线程:平均耗时 2.48s,CPU 100%
远程模式 80线程:平均耗时 2.69s,CPU 100%
远程模式200线程:平均耗时 3.27s,CPU 100%
远程模式500线程:平均耗时 3.29s,CPU 100%
反射模式+普通二进制序列化 [10W对象 + 序列化数据12M]测试结果
本地模式  1线程:平均耗时  3.1s,CPU 100%
远程模式  1线程:平均耗时 8.17s,CPU 100%
远程模式 20线程:平均耗时 4.26s,CPU 100%
远程模式 25线程:平均耗时 4.26s,CPU 100%
远程模式 40线程:平均耗时 4.25s,CPU 100%
反射模式+成员识别二进制序列化 [10W对象 + 序列化数据35M]测试结果
本地模式  1线程:平均耗时 3.26s,CPU 100%
远程模式  1线程:平均耗时 8.21s,CPU 100%
远程模式 20线程:平均耗时 4.52s,CPU 100%
远程模式 25线程:平均耗时 4.64s,CPU 100%
远程模式 40线程:平均耗时 4.67s,CPU 100%
可以看到序列化模式的选择,对于性能影响不大。反射模式相差不到10%,代码生成模式+远程模式也在40%以下。 在本地模式中,反射模式模式与代码生成模式性能相差2倍以上;在远程模式中,反射模式模式与代码生成模式性能相差1-2倍左右。
回复 点赞
showjim 2014年02月16日
引用 3 楼 devmiao 的回复:
感谢分享。不过原生32bit环境下,CLR对内存总量有天然的限制,不知道lz可有研究。
既然使用的内存数据库比较大,为什么不用64bit系统呢?
回复 点赞
绿色夹克衫 2014年02月01日
用64位编译不就解决了?
引用 3 楼 devmiao 的回复:
感谢分享。不过原生32bit环境下,CLR对内存总量有天然的限制,不知道lz可有研究。
回复 点赞
devmiao 2014年02月01日
感谢分享。不过原生32bit环境下,CLR对内存总量有天然的限制,不知道lz可有研究。
回复 点赞
绿色夹克衫 2014年02月01日
好东西,帮顶一下
回复 点赞
Regan-lin 2014年01月31日
过年都还在搞,不Mark都对不起楼主
回复 点赞
发动态
发帖子
非技术区
创建于2007-09-28

3896

社区成员

6.4w+

社区内容

.NET技术 非技术区
社区公告
暂无公告