程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 高並發、海量數據處理盡量少使用using也能提升效率,海量using

高並發、海量數據處理盡量少使用using也能提升效率,海量using

編輯:C#入門知識

高並發、海量數據處理盡量少使用using也能提升效率,海量using


 

 

      剛開始看到這個標題,估計很多人都雲裡霧裡的。

  請看下面兩段:

第一種方式:

                MemoryStream stream = new MemoryStream();
          string text = "aasasdfasdfad;sas;fkqeworpkqwefkasdjfasdjf"; byte[] buff = System.Text.ASCIIEncoding.ASCII.GetBytes(text); stream.Write(buff, 0, buff.Length); stream.Flush(); stream.Close(); stream.Dispose();

第二種方式:

            string text = "aasasdfasdfad;sas;fkqeworpkqwefkasdjfasdjf";
            using (MemoryStream stream = new MemoryStream())
            {
                byte[] buff = System.Text.ASCIIEncoding.ASCII.GetBytes(text);
                stream.Write(buff, 0, buff.Length);
                stream.Flush();
                stream.Close();
            }

不僅僅是我,估計一個老鳥程序員,大都會選擇方法二,雖然方法一和方法二實現相同的功能,但是方法二帶著套比較保險,即便我們失手,不會制造出垃圾來(這話聽著怪怪的,能理解我在說什麼就好)。之後,我在做一些消息處理機制的接收、處理、分發測試中,發現使用using關鍵字和不用using關鍵字,效率有著很大差異,不使用using關鍵字效率明顯偏高,隊列中緩存數據明顯大減,而且基本不再出現容器不足溢出現象,這是為什麼呢?答案馬上揭曉。

以下是通過反匯編工具所得的一種類似匯編語言(如果以下真是匯編語言,就當我前面"類似"兩字說錯了,跟我當初學的匯編語言不一樣。這個應該是.net架構可識別的中間語言)

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代碼大小       65 (0x41)
  .maxstack  4
  .locals init ([0] string text,
           [1] class [mscorlib]System.IO.MemoryStream 'stream',
           [2] uint8[] buff)
  IL_0000:  nop
  IL_0001:  ldstr      "aasasdfasdfad;sas;fkqeworpkqwefkasdjfasdjf"
  IL_0006:  stloc.0
  IL_0007:  newobj     instance void [mscorlib]System.IO.MemoryStream::.ctor()
  IL_000c:  stloc.1
  IL_000d:  call       class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_ASCII()
  IL_0012:  ldloc.0
  IL_0013:  callvirt   instance uint8[] [mscorlib]System.Text.Encoding::GetBytes(string)
  IL_0018:  stloc.2
  IL_0019:  ldloc.1
  IL_001a:  ldloc.2
  IL_001b:  ldc.i4.0
  IL_001c:  ldloc.2
  IL_001d:  ldlen
  IL_001e:  conv.i4
  IL_001f:  callvirt   instance void [mscorlib]System.IO.Stream::Write(uint8[],
                                                                       int32,
                                                                       int32)
  IL_0024:  nop
  IL_0025:  ldloc.1
  IL_0026:  callvirt   instance void [mscorlib]System.IO.Stream::Flush()
  IL_002b:  nop
  IL_002c:  ldloc.1
  IL_002d:  callvirt   instance void [mscorlib]System.IO.Stream::Close()
  IL_0032:  nop
  IL_0033:  ldloc.1
  IL_0034:  callvirt   instance void [mscorlib]System.IO.Stream::Dispose()
  IL_0039:  nop
  IL_0040:  ret
} // end of method Program::Main

以上是方法一,所得中間語言,看起來非常干淨、流暢。下面看看方法二的:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代碼大小       79 (0x4f)
  .maxstack  4
  .locals init ([0] string text,
           [1] class [mscorlib]System.IO.MemoryStream 'stream',
           [2] uint8[] buff,
           [3] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  ldstr      "aasasdfasdfad;sas;fkqeworpkqwefkasdjfasdjf"
  IL_0006:  stloc.0
  IL_0007:  newobj     instance void [mscorlib]System.IO.MemoryStream::.ctor()
  IL_000c:  stloc.1
  .try
  {
    IL_000d:  nop
    IL_000e:  call       class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_ASCII()
    IL_0013:  ldloc.0
    IL_0014:  callvirt   instance uint8[] [mscorlib]System.Text.Encoding::GetBytes(string)
    IL_0019:  stloc.2
    IL_001a:  ldloc.1
    IL_001b:  ldloc.2
    IL_001c:  ldc.i4.0
    IL_001d:  ldloc.2
    IL_001e:  ldlen
    IL_001f:  conv.i4
    IL_0020:  callvirt   instance void [mscorlib]System.IO.Stream::Write(uint8[],
                                                                         int32,
                                                                         int32)
    IL_0025:  nop
    IL_0026:  ldloc.1
    IL_0027:  callvirt   instance void [mscorlib]System.IO.Stream::Flush()
    IL_002c:  nop
    IL_002d:  ldloc.1
    IL_002e:  callvirt   instance void [mscorlib]System.IO.Stream::Close()
    IL_0033:  nop
    IL_0034:  nop
    IL_0035:  leave.s    IL_0047
  }  // end .try
  finally
  {
    IL_0037:  ldloc.1
    IL_0038:  ldnull
    IL_0039:  ceq
    IL_003b:  stloc.3
    IL_003c:  ldloc.3
    IL_003d:  brtrue.s   IL_0046
    IL_003f:  ldloc.1
    IL_0040:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_0045:  nop
    IL_0046:  endfinally
  }  // end handler
  IL_0047:  pop
  IL_0048:  ret
} // end of method Program::Main

(紅字部分)這下能看出問題來了吧,本來是功能相同的兩段代碼,但是在方法二中,多出了一個try..finally模塊,多出一個初始存儲元的申請CS$4$0000,多出很多行相對來說算是賦址操作。這就是導致方法二效率低的主要原因。

  但是剛剛我們也提到了,雖然方法一和方法二實現相同的功能,但是方法二帶著套比較保險,即便我們失手,不會制造出垃圾來。即使是你忘記使用.close()、.dispose()方法釋放資源,using還是會自動幫你處理好你遺忘的的壞事。

  所以在一般不要求高效開發中,盡量使用using,但是在處理高並發、海量數據等等情況下,盡量不要讓using出現。不過現在好了,自從接觸erlang後,它處理消息確實比C#/java/C++高效多了。

 


 

  還有一點忘記說了,我用消息泵處理消息隊列,消息泵放到一個using裡面,這會導致所有消息都會在這個using包裹中處理。


 

  這一段是我補充上來的,因為有位大大說了一個非常准確的話,當時我寫貼太快,沒有深思,這次做下補充。

#7樓 2014-10-23 21:59 eflay   try catch 如果沒有捕獲到異常的話,是幾乎不會降低速度的,另外,調用了close就不需要dispose了,所以總覺得對你所謂的效率差距保持懷疑。   #10樓[樓主] 2014-10-24 09:07 小堯弟   @eflay
呵呵,我這麼說確實有問題的,不過服務器端的很多異常,尤其是mq/消息類的寧可拋棄,也不要捕捉,獲取/發送異常,可以再來一次;如果因為性能讓服務器假死,或者是當機,那就真的有問題了,我這個題目不好,跟內容有點出入,因為中間可能出現的很多問題我都沒法在這麼一小篇中說的清楚。   你的提示對其他看帖的人很有幫助,寫貼不能誤人子弟、毀人不倦不是嗎?   舉個例子吧,mq消息接收,消息格式從老格式轉化新格式,但是服務端忘記處理了,直接導致接收消息時轉換格式異常使得性能出現問題,隊列溢出,消息服務假死狀態。  

 


SQL怎快速處理海量數據?

在以下的文章中,我將以“辦公自動化”系統為例,探討如何在有著1000萬條數據的MS SQL SERVER數據庫中實現快速的數據提取和數據分頁。以下代碼說明了我們實例中數據庫的“紅頭文件”一表的部分數據結構:

CREATE TABLE [dbo].[TGongwen] ( --TGongwen是紅頭文件表名

[Gid] [int] IDENTITY (1, 1) NOT NULL ,
--本表的id號,也是主鍵

[title] [varchar] (80) COLLATE Chinese_PRC_CI_AS NULL ,
--紅頭文件的標題

[fariqi] [datetime] NULL ,
--發布日期

[neibuYonghu] [varchar] (70) COLLATE Chinese_PRC_CI_AS NULL ,
--發布用戶

[reader] [varchar] (900) COLLATE Chinese_PRC_CI_AS NULL ,

--需要浏覽的用戶。每個用戶中間用分隔符“,”分開

) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

下面,我們來往數據庫中添加1000萬條數據:

declare @i int

set @i=1

while @i<=250000

begin

insert into Tgongwen(fariqi,neibuyonghu,reader,title) values('2004-2-5','通信科','通信科,辦公室,王局長,劉局長,張局長,admin,刑偵支隊,特勤支隊,交巡警支隊,經偵支隊,戶政科,治安支隊,外事科','這是最先的25萬條記錄')

set @i=@i+1

end

GO

declare @i int

set @i=1

while @i<=250000

begin

insert into Tgongwen(fariqi,neibuyonghu,reader,title) values('2004-9-16','辦公室','辦公室,通信科,王局長,劉局長,張局長,admin,刑偵支隊,特勤支隊,交巡警支隊,經偵支隊,戶政科,外事科','這是中間的25萬條記錄')

set @i=@i+1

end

GO

declare @h int

set @h=1

while @h<=100

begin

declare @i int

set @i=2002

while @i<=2003

begin

declare @j int

set @j=0

while @j<50

begin

declare @k int

set @k=0

while @k<50

begin

insert into Tgongwen(fariqi,neibuyonghu,reader,title) values(cast(@i as varchar(4))+'-8-15 3:'+cast(@j as varchar(2))+':'+cast(@j as varchar(2)),'通信科','辦公室,通信科,王......余下全文>>
 

大數據高並發系統架構實戰方案(LVS負載均衡、Nginx、共享存儲、海量數據、隊列緩存)

去51cto網上博客搜索看吧,也有很多類似的書籍
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved