本文以一组Entity vs Dataset的性能测试数据为基础,比较以Entity作为DTO和Dataset作为DTO的性能差异。测试可能不一定严密,但是一定程度上能够比较出优劣。希望能为您选择 .Net下不同的数据承载方式、序列化方式、DTO的选择,多一点参考。在本测试中,每个执行过程,对于Entity,我们将先用DataReader读出数据,使用索引将数据填充到Entity,序列化,再反序列化;对于Dataset,将先读取所有数据到Dataset,序列化,再反序列化,最后通过索引填充Dataset中的数据到Entity。也就是说,无论对Entity还是Dataset,我们都尽可能的取其最佳性能的执行方式,从而将性能瓶颈留在了序列化和反序列化方式上。您可以注意到,Dataset的序列化和反序列化性能是非常突出的,但是,我们基于Entity的自定义序列化方式的综合性能,超越了Dataset。
04/18补充:新增.NET JSON序列化对照。关于JSON的更多介绍请参见:http://www.json.org/。不过值得一提的是,官方提供的.Net实现写得那个烂得简直没话说。本测试使用Teddy修改由化后的.Net版本,性能是官方版本的30-40倍。
测试报告
就让我们先从一个测试报告开始,该测试读取Northwind数据库中Order Details Extended视图的所有数据,RepeatTime表示每个步骤(读数据、序列化、反序列化等等着每个步骤)被重复的次数。表中的时间数值单位为毫秒。
Ilungasoft Framework Data Access & Entities Serialization Performance Test
Title | Read Data Time | Serialize Time | Serialized Xml Size | DeserializeTime | Total Run Time |
---|---|---|---|---|---|
Entities Xml Serialize | 844 | 1766 | 702783 | 1750 | 4360 |
Entities Soap Serialize | 328 | 4094 | 3031007 | 6203 | 10625 |
Entities Custom Serialize | 359 | 594 | 598565 | 625 | 1578 |
DataSet Serialize | 515 | 532 | 586200 | 2047 | 3094 |
Entities JSON Serialize | 484 | 625 | 325298 | 641 | 1750 |
Title | Read Data Time | Serialize Time | Serialized Xml Size | Deserialize Time | Total Run Time |
---|---|---|---|---|---|
Entities Xml Serialize | 1093 | 2594 | 702783 | 3797 | 7484 |
Entities Soap Serialize | 734 | 8032 | 3031007 | 12000 | 20766 |
Entities Custom Serialize | 671 | 1188 | 598565 | 1234 | 3093 |
DataSet Serialize | 657 | 1062 | 586200 | 6563 | 8282 |
Entities JSON Serialize | 781 | 1094 | 325298 | 1093 | 2968 |
Title | Read Data Time | Serialize Time | Serialized Xml Size | Deserialize Time | Total Run Time |
---|---|---|---|---|---|
Entities Xml Serialize | 938 | 4140 | 702783 | 5547 | 10625 |
Entities Soap Serialize | 1094 | 12578 | 3031007 | 18891 | 32563 |
Entities Custom Serialize | 1140 | 1922 | 598565 | 2188 | 5250 |
DataSet Serialize | 1156 | 1438 | 586200 | 14984 | 17578 |
Entities JSON Serialize | 1141 | 1656 | 325298 | 1703 | 4500 |
Title | Read Data Time | Serialize Time | Serialized Xml Size | Deserialize Time | Total Run Time |
---|---|---|---|---|---|
Entities Xml Serialize | 1594 | 5047 | 702783 | 6968 | 13609 |
Entities Soap Serialize | 1391 | 16844 | 3031007 | 26093 | 44328 |
Entities Custom Serialize | 1875 | 2469 | 598565 | 2735 | 7079 |
DataSet Serialize | 1828 | 2093 | 586200 | 25969 | 29890 |
Entities JSON Serialize | 1719 | 2437 | 325298 | 2500 | 6656 |
解析
以上的测试中,除了Dataset Serialize是使用Dataset作为DTO来序列化和反序列化数据之外,其他的都是使用Entity方式来处理。Xml Serialize表示系统默认的XmlSerializer序列化方式,SoapSerilialize自然是系统默认的SoapFormatter序列化,CustomSerialize则是自定义的序列化方式(目前采用的是自定义序列化+XmlSerializer反序列化结合的方式)。Json Serialization为Teddy的Json优化版本。
测试代码

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

更多代码我就不列举了,请自行下载下面的源码。
下载
下载测试框架及源码 (本示例源码包含在新版本的Ilungasoft Framework v1.4.4的目录中的dist\Sample5)
小结
本测试示例的目的并不是要终结Dataset作为DTO,尽管Entity作为DTO的性能是可以超越Dataset的,但Teddy觉得,Dataset的性能确实是相当好的,作为一个通用的DTO还是非常适合的(尤其是可以和异构的其他.Net系统方便共享和传递数据)。
补遗:
后续的测试中还发现,无论是XmlSerializer的序列化方式都不够稳定,特别是反序列化时,尤其是对符合类型和数组的序列化。因此,对于大多数基于.Net的程序构架,Teddy还是推荐使用Dataset作为DTO,除非对性能要求非常高时在使用自定义的序列化方式。
4/19:
更新了CustomSerizlize算法,使得其执行时间仅为Dataset的1/2 - 1/10。数据量越大,自定义序列化的优势就越明显。
新增的JSON序列化性能基本和自定义Xml 序列化相当,当数据量较大时,要比自定义Xml序列化方式稍好一点点。
但是,请注意,JSON的序列化后的文本大小只有Dataset的一半,对于需要远程通信的程序来讲,JSON方式将极大的减少需要通信的数据量,因此,JSON方式带来的实际的性能提升可能会更大。