常用WebServices返回数据的4种方法比较
2009-09-09 12:49
495 查看
以前经常在群里听到朋友们说WebServices的性能特别的慢,说的如何如何。说实话,WebServices的确比调用本地数据要慢一些,可
是究竟有多慢,真的如朋友们说的那么难以忍受吗?我个人感觉,多半原因在处理的方式上。让我们亲自编写测试代码,来证明这一切吧。文章由于是我一段时间的
总结篇,因此难免参杂个人主观因素,说的不对的地方,还请多多批评。以下我们主要从调用WebServices的方法的特点、应用场景、测试结果三个方面
来进行下说明分析。
1. 直接返回DataSet对象
特点:直接返回DataSet对象。
应用场景:1.内网。2.外网且数据量在kb级别时。
2.返回DataSet对象用Binary序列化后的字节数组
特点:字节数组流的处理模式。
应用场景:较大数据交换。
3.返回DataSetSurrogate对象用Binary序列化后的字节数组
特点:使用微软提供的开源组件进行序列化,依然是字节流的处理模式。详情请参考:http://support.microsoft.com/kb/829740/zh-cn
应用场景: 较大数据交换。
4.返回DataSetSurrogate对象用Binary序列化并Zip压缩后的字节数组
特点:使用微软提供的开源组件对字节流数组进行压缩后传递,依然是字节流的处理模式。详情请参考:http://support.microsoft.com/kb/829740/zh-cn
应用场景:外网环境需要进行大数据量网络数据传递时,建议采用此种方法。也是笔者强烈向大家推荐使用的一种方法。
WebServices的代码如下:
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
WebServices
using
System;
using
System.Collections.Generic;
using
System.Web;
using
System.Web.Services;
using
System.Data;
using
Microsoft.Practices.EnterpriseLibrary.Common;
using
Microsoft.Practices.EnterpriseLibrary.Data;
using
System.IO;
using
System.IO.Compression;
using
System.Runtime.Serialization.Formatters.Binary;
namespace
WebService1
{
///
<summary>
///
Service1 的摘要说明
///
</summary>
[WebService(Namespace
=
" http://tempuri.org/ "
)]
[WebServiceBinding(ConformsTo
=
WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(
false
)]
public
class
Service1 : System.Web.Services.WebService
{
[WebMethod(Description
=
"
直接返回DataSet对象
"
)]
public
DataSet GetDataSet()
{
string
sql
=
"
select * from Customers
"
;
Database db
=
DatabaseFactory.CreateDatabase();
DataSet ds
=
db.ExecuteDataSet(CommandType.Text,sql);
return
ds;
}
[WebMethod(Description
=
"
返回DataSet对象用Binary序列化后的字节数组
"
)]
public
byte
[] GetBytes()
{
DataSet ds
=
GetDataSet();
BinaryFormatter bf
=
new
BinaryFormatter();
MemoryStream ms
=
new
MemoryStream();
bf.Serialize(ms, ds);
byte
[] buffer
=
ms.ToArray();
return
buffer;
}
[WebMethod(Description
=
"
返回DataSetSurrogate对象用Binary序列化后的字节数组
"
)]
public
byte
[] GetDataSetSurrogateBytes()
{
DataSet ds
=
GetDataSet();
DataSetSurrogate dss
=
new
DataSetSurrogate(ds);
BinaryFormatter bf
=
new
BinaryFormatter();
MemoryStream ms
=
new
MemoryStream();
bf.Serialize(ms,dss);
byte
[] buffer
=
ms.ToArray();
return
buffer;
}
[WebMethod(Description
=
"
返回DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组
"
)]
public
byte
[] GetDataSetSurrogateZipBytes()
{
DataSet DS
=
GetDataSet();
DataSetSurrogate dss
=
new
DataSetSurrogate(DS);
BinaryFormatter bf
=
new
BinaryFormatter();
MemoryStream ms
=
new
MemoryStream();
bf.Serialize(ms, dss);
byte
[] buffer
=
ms.ToArray();
byte
[] Zipbuffer
=
Compress(buffer);
return
Zipbuffer;
}
//
压缩压缩后的字节数组
public
byte
[] Compress(
byte
[] data)
{
MemoryStream ms
=
new
MemoryStream();
Stream zipStream
=
new
GZipStream(ms, CompressionMode.Compress,
true
);
zipStream.Write(data,
0
, data.Length);
zipStream.Close();
ms.Position
=
0
;
byte
[] buffer
=
new
byte
[ms.Length];
ms.Read(buffer,
0
,
int
.Parse(ms.Length.ToString()));
return
buffer;
}
}
}
客户端调用WebServices的代码如下:
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
客户端调用WebServices
using
System;
using
System.Collections.Generic;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
WebServicesClient.localhost;
using
System.Data;
using
System.Runtime.Serialization.Formatters.Binary;
using
System.IO;
using
System.Diagnostics;
namespace
WebServicesClient
{
public
partial
class
_Default : System.Web.UI.Page
{
Service1 s
=
new
Service1();
protected
void
Page_Load(
object
sender, EventArgs e)
{
}
//
直接返回DataSet对象
protected
void
Button1_Click(
object
sender, EventArgs e)
{
Stopwatch sw
=
new
Stopwatch();
sw.Start();
DataSet ds
=
s.GetDataSet();
GridView1.DataSource
=
ds.Tables[
0
].DefaultView;
GridView1.DataBind();
sw.Stop();
Label1.Text
=
string
.Format(
"
耗时:{0}毫秒
"
, sw.ElapsedMilliseconds.ToString());
}
//
得到DataSet对象用Binary序列化后的字节数组
protected
void
Button2_Click(
object
sender, EventArgs e)
{
Stopwatch sw
=
new
Stopwatch();
sw.Start();
byte
[] buffer
=
s.GetBytes();
BinaryFormatter bf
=
new
BinaryFormatter();
DataSet ds
=
bf.Deserialize(
new
MemoryStream(buffer))
as
DataSet;
GridView1.DataSource
=
ds.Tables[
0
].DefaultView;
GridView1.DataBind();
sw.Stop();
Label2.Text
=
string
.Format(
"
耗时:{1}毫秒;数据大小:{0}
"
, buffer.Length.ToString(), sw.ElapsedMilliseconds.ToString());
}
//
得到DataSetSurrogate对象用Binary序列化后的字节数组
protected
void
Button3_Click(
object
sender, EventArgs e)
{
Stopwatch sw
=
new
Stopwatch();
sw.Start();
byte
[] buffer
=
s.GetDataSetSurrogateBytes();
BinaryFormatter bf
=
new
BinaryFormatter();
DataSetSurrogate dss
=
bf.Deserialize(
new
MemoryStream(buffer))
as
DataSetSurrogate;
DataSet ds
=
dss.ConvertToDataSet();
GridView1.DataSource
=
ds.Tables[
0
].DefaultView;
GridView1.DataBind();
sw.Stop();
Label3.Text
=
string
.Format(
"
耗时:{1}毫秒;数据大小:{0}
"
, buffer.Length.ToString(), sw.ElapsedMilliseconds.ToString());
}
//
得到DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组
protected
void
Button4_Click(
object
sender, EventArgs e)
{
Stopwatch sw
=
new
Stopwatch();
sw.Start();
byte
[] zipBuffer
=
s.GetDataSetSurrogateZipBytes();
byte
[] buffer
=
UnZip.Decompress(zipBuffer);
BinaryFormatter bf
=
new
BinaryFormatter();
DataSetSurrogate dss
=
bf.Deserialize(
new
MemoryStream(buffer))
as
DataSetSurrogate;
DataSet ds
=
dss.ConvertToDataSet();
GridView1.DataSource
=
ds.Tables[
0
].DefaultView;
GridView1.DataBind();
sw.Stop();
Label4.Text
=
string
.Format(
"
耗时:{1}毫秒;数据大小:{0}
"
,zipBuffer.Length.ToString(),sw.ElapsedMilliseconds.ToString());
}
}
}
测试的结果按照先后顺序如下图所示:
![](http://images.cnblogs.com/cnblogs_com/wlb/2009-4-13.jpg)
关于测试结果的特殊说明:由于测试环境是在本地,数据量也不是很大,测试的结果离实际情况还不是很接近,如果大家有条件的话,可以测试一下,同时希望把测试的结果提供给大家参考。
最后,为了方便大家,这里还提供了源码下载,下载地址如下:
/Files/wlb/WebServiceSummary.rar
关于源代码的特殊说明:笔者这里的开发环境为VS2008中文版sp1+SQLServer2008sp1。数据库为Northwind数据库。
#MySignature { BORDER-RIGHT: #e5e5e5 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #e5e5e5 1px solid; PADDING-LEFT: 60px; BACKGROUND: url(http://wlb.cnblogs.com/images/cnblogs_com/wlb/1.jpg) #fffefe no-repeat 1% 50%; PADDING-BOTTOM: 10px; BORDER-LEFT: #e5e5e5 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #e5e5e5 1px solid } #MySignature A:link { COLOR: #f60 } #MySignature A:visited { COLOR: #f60 } #MySignature A:active { COLOR: #f60 } #MySignature A:hover { COLOR: #f60; TEXT-DECORATION: underline } 作者:深山老林
出处:http://wlb.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
是究竟有多慢,真的如朋友们说的那么难以忍受吗?我个人感觉,多半原因在处理的方式上。让我们亲自编写测试代码,来证明这一切吧。文章由于是我一段时间的
总结篇,因此难免参杂个人主观因素,说的不对的地方,还请多多批评。以下我们主要从调用WebServices的方法的特点、应用场景、测试结果三个方面
来进行下说明分析。
1. 直接返回DataSet对象
特点:直接返回DataSet对象。
应用场景:1.内网。2.外网且数据量在kb级别时。
2.返回DataSet对象用Binary序列化后的字节数组
特点:字节数组流的处理模式。
应用场景:较大数据交换。
3.返回DataSetSurrogate对象用Binary序列化后的字节数组
特点:使用微软提供的开源组件进行序列化,依然是字节流的处理模式。详情请参考:http://support.microsoft.com/kb/829740/zh-cn
应用场景: 较大数据交换。
4.返回DataSetSurrogate对象用Binary序列化并Zip压缩后的字节数组
特点:使用微软提供的开源组件对字节流数组进行压缩后传递,依然是字节流的处理模式。详情请参考:http://support.microsoft.com/kb/829740/zh-cn
应用场景:外网环境需要进行大数据量网络数据传递时,建议采用此种方法。也是笔者强烈向大家推荐使用的一种方法。
WebServices的代码如下:
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
WebServices
using
System;
using
System.Collections.Generic;
using
System.Web;
using
System.Web.Services;
using
System.Data;
using
Microsoft.Practices.EnterpriseLibrary.Common;
using
Microsoft.Practices.EnterpriseLibrary.Data;
using
System.IO;
using
System.IO.Compression;
using
System.Runtime.Serialization.Formatters.Binary;
namespace
WebService1
{
///
<summary>
///
Service1 的摘要说明
///
</summary>
[WebService(Namespace
=
" http://tempuri.org/ "
)]
[WebServiceBinding(ConformsTo
=
WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(
false
)]
public
class
Service1 : System.Web.Services.WebService
{
[WebMethod(Description
=
"
直接返回DataSet对象
"
)]
public
DataSet GetDataSet()
{
string
sql
=
"
select * from Customers
"
;
Database db
=
DatabaseFactory.CreateDatabase();
DataSet ds
=
db.ExecuteDataSet(CommandType.Text,sql);
return
ds;
}
[WebMethod(Description
=
"
返回DataSet对象用Binary序列化后的字节数组
"
)]
public
byte
[] GetBytes()
{
DataSet ds
=
GetDataSet();
BinaryFormatter bf
=
new
BinaryFormatter();
MemoryStream ms
=
new
MemoryStream();
bf.Serialize(ms, ds);
byte
[] buffer
=
ms.ToArray();
return
buffer;
}
[WebMethod(Description
=
"
返回DataSetSurrogate对象用Binary序列化后的字节数组
"
)]
public
byte
[] GetDataSetSurrogateBytes()
{
DataSet ds
=
GetDataSet();
DataSetSurrogate dss
=
new
DataSetSurrogate(ds);
BinaryFormatter bf
=
new
BinaryFormatter();
MemoryStream ms
=
new
MemoryStream();
bf.Serialize(ms,dss);
byte
[] buffer
=
ms.ToArray();
return
buffer;
}
[WebMethod(Description
=
"
返回DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组
"
)]
public
byte
[] GetDataSetSurrogateZipBytes()
{
DataSet DS
=
GetDataSet();
DataSetSurrogate dss
=
new
DataSetSurrogate(DS);
BinaryFormatter bf
=
new
BinaryFormatter();
MemoryStream ms
=
new
MemoryStream();
bf.Serialize(ms, dss);
byte
[] buffer
=
ms.ToArray();
byte
[] Zipbuffer
=
Compress(buffer);
return
Zipbuffer;
}
//
压缩压缩后的字节数组
public
byte
[] Compress(
byte
[] data)
{
MemoryStream ms
=
new
MemoryStream();
Stream zipStream
=
new
GZipStream(ms, CompressionMode.Compress,
true
);
zipStream.Write(data,
0
, data.Length);
zipStream.Close();
ms.Position
=
0
;
byte
[] buffer
=
new
byte
[ms.Length];
ms.Read(buffer,
0
,
int
.Parse(ms.Length.ToString()));
return
buffer;
}
}
}
客户端调用WebServices的代码如下:
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
客户端调用WebServices
using
System;
using
System.Collections.Generic;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
WebServicesClient.localhost;
using
System.Data;
using
System.Runtime.Serialization.Formatters.Binary;
using
System.IO;
using
System.Diagnostics;
namespace
WebServicesClient
{
public
partial
class
_Default : System.Web.UI.Page
{
Service1 s
=
new
Service1();
protected
void
Page_Load(
object
sender, EventArgs e)
{
}
//
直接返回DataSet对象
protected
void
Button1_Click(
object
sender, EventArgs e)
{
Stopwatch sw
=
new
Stopwatch();
sw.Start();
DataSet ds
=
s.GetDataSet();
GridView1.DataSource
=
ds.Tables[
0
].DefaultView;
GridView1.DataBind();
sw.Stop();
Label1.Text
=
string
.Format(
"
耗时:{0}毫秒
"
, sw.ElapsedMilliseconds.ToString());
}
//
得到DataSet对象用Binary序列化后的字节数组
protected
void
Button2_Click(
object
sender, EventArgs e)
{
Stopwatch sw
=
new
Stopwatch();
sw.Start();
byte
[] buffer
=
s.GetBytes();
BinaryFormatter bf
=
new
BinaryFormatter();
DataSet ds
=
bf.Deserialize(
new
MemoryStream(buffer))
as
DataSet;
GridView1.DataSource
=
ds.Tables[
0
].DefaultView;
GridView1.DataBind();
sw.Stop();
Label2.Text
=
string
.Format(
"
耗时:{1}毫秒;数据大小:{0}
"
, buffer.Length.ToString(), sw.ElapsedMilliseconds.ToString());
}
//
得到DataSetSurrogate对象用Binary序列化后的字节数组
protected
void
Button3_Click(
object
sender, EventArgs e)
{
Stopwatch sw
=
new
Stopwatch();
sw.Start();
byte
[] buffer
=
s.GetDataSetSurrogateBytes();
BinaryFormatter bf
=
new
BinaryFormatter();
DataSetSurrogate dss
=
bf.Deserialize(
new
MemoryStream(buffer))
as
DataSetSurrogate;
DataSet ds
=
dss.ConvertToDataSet();
GridView1.DataSource
=
ds.Tables[
0
].DefaultView;
GridView1.DataBind();
sw.Stop();
Label3.Text
=
string
.Format(
"
耗时:{1}毫秒;数据大小:{0}
"
, buffer.Length.ToString(), sw.ElapsedMilliseconds.ToString());
}
//
得到DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组
protected
void
Button4_Click(
object
sender, EventArgs e)
{
Stopwatch sw
=
new
Stopwatch();
sw.Start();
byte
[] zipBuffer
=
s.GetDataSetSurrogateZipBytes();
byte
[] buffer
=
UnZip.Decompress(zipBuffer);
BinaryFormatter bf
=
new
BinaryFormatter();
DataSetSurrogate dss
=
bf.Deserialize(
new
MemoryStream(buffer))
as
DataSetSurrogate;
DataSet ds
=
dss.ConvertToDataSet();
GridView1.DataSource
=
ds.Tables[
0
].DefaultView;
GridView1.DataBind();
sw.Stop();
Label4.Text
=
string
.Format(
"
耗时:{1}毫秒;数据大小:{0}
"
,zipBuffer.Length.ToString(),sw.ElapsedMilliseconds.ToString());
}
}
}
测试的结果按照先后顺序如下图所示:
![](http://images.cnblogs.com/cnblogs_com/wlb/2009-4-13.jpg)
关于测试结果的特殊说明:由于测试环境是在本地,数据量也不是很大,测试的结果离实际情况还不是很接近,如果大家有条件的话,可以测试一下,同时希望把测试的结果提供给大家参考。
最后,为了方便大家,这里还提供了源码下载,下载地址如下:
/Files/wlb/WebServiceSummary.rar
关于源代码的特殊说明:笔者这里的开发环境为VS2008中文版sp1+SQLServer2008sp1。数据库为Northwind数据库。
#MySignature { BORDER-RIGHT: #e5e5e5 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #e5e5e5 1px solid; PADDING-LEFT: 60px; BACKGROUND: url(http://wlb.cnblogs.com/images/cnblogs_com/wlb/1.jpg) #fffefe no-repeat 1% 50%; PADDING-BOTTOM: 10px; BORDER-LEFT: #e5e5e5 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #e5e5e5 1px solid } #MySignature A:link { COLOR: #f60 } #MySignature A:visited { COLOR: #f60 } #MySignature A:active { COLOR: #f60 } #MySignature A:hover { COLOR: #f60; TEXT-DECORATION: underline } 作者:深山老林
出处:http://wlb.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关文章推荐
- 常用WebServices返回数据的4种方法比较
- 常用WebServices返回数据的4种方法比较
- 常用WebServices返回数据的4种方法比较
- 常用WebServices返回数据的4种方法比较
- 常用WebServices返回数据的4种方法比较
- 常用WebServices返回数据的4种方法比较
- 常用WebServices返回数据的4种方法比较
- 【转】 常用WebServices返回数据的4种方法比较
- 常用WebServices返回数据的4种方法比较 (转)
- 常用WebServices返回数据的4种方法比较
- 常用WebServices返回数据的4种方法比较
- WebServices返回数据的4种方法比较
- WebServices返回数据的4种方法比较 1
- WebServices返回数据的4种方法比较
- WebServices返回数据的4种方法比较 2
- WebServices返回数据的4种方法比较
- WebServices返回数据的4种方法比较
- 通过WebService返回数据的四种方法比较
- PHP中4种常用的抓取网络数据方法
- PHP中4种常用的抓取网络数据方法