zoukankan      html  css  js  c++  java
  • 高并发、海量数据处理尽量少使用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关键字效率明显偏高,MQ队列占用明显偏小,这是为什么呢?答案马上揭晓。

    以下是通过反汇编工具所得的中间语言(IL)

    .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

      第二段IL中间红色部分即为不同

    [3] bool  CS$4$0000)
    IL_000d: nop                停止几个时钟周期
    IL_000d: nop
    IL_0035: leave.s  IL_0047    退出受保护的代码区域,无条件将控制转移到目标指令
    IL_0038: ldnull              将空引用(O 类型)推送到计算堆栈上
    IL_0039: ceq                 比较两个值。如果这两个值相等,则将整数值 1 (int32) 推送到计算堆栈上;否则,将 0 (int32) 推送到计算堆栈上
    IL_003b: stloc.3             从计算堆栈的顶部弹出当前值并将其存储到索引 3 处的局部变量列表中
    IL_003c: ldloc.3             将索引 3 处的局部变量加载到计算堆栈上
    IL_003d: brtrue.s  IL_0046   如果 value 为 true、非空或非零,则将控制转移到目标指令
    IL_003f: ldloc.1             将索引 1 处的局部变量加载到计算堆栈上
    IL_0045: nop
    IL_0046: endfinally          将控制从异常块的 fault 或 finally 子句转移回公共语言结构 (CLI) 异常处理程序

    IL指令汇总

      但是刚刚我们也提到了,虽然方法一和方法二实现相同的功能,但是方法二带着套比较保险,即便我们失手,不会制造出垃圾来。即使是你忘记使用.close()、.dispose()方法释放资源,using还是会自动帮你处理好你遗忘的的坏事。

      所以在一般不要求高效开发中,尽量使用using,但是在处理高并发、海量数据等等情况下,尽量不要让using出现。


     提示:

      try..catch有一定的代码优化能力,少量代码测试,try..catch可能更优


     
     
     
     
     
  • 相关阅读:
    经常使用排序算法时间复杂度和空间复杂度简析
    Android触碰事件
    opencv矩阵运算(2)
    [ACM] HDU 1400 Mondriaan's Dream (状态压缩,长2宽1长方形铺满)
    指针知识梳理8- 指针的指针
    Git学习笔记(一)
    Object-c Associated Object
    YTUOJ-计算该日在本年中是第几天(用户自己定义类型)
    MYSQL源代码编译的变动
    手机端小问题整理
  • 原文地址:https://www.cnblogs.com/preacher/p/4046445.html
Copyright © 2011-2022 走看看