asp.net C# 中的 static 关键字(1/3)

01:  /// <summary>
02:  /// 使用字节数组中的值初始 zipinteger 结构的新实例
03:  /// 注意:本构造函数会破坏传入的 bits 参数的值。
04:  /// </summary>
05:  /// <param name="bits">顺序为 big-endian 的字节值的数组</param>
06:  public zipinteger(byte[] bits)
07:  {
08:    if (bits == null) throw new argumentnullexception("bits");
09:    if (bits.length < 1 || bits.length > 9) throw new argumentexception("invalid length", "bits");
10:    byte[] mask = { 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 };
11:    if (bits.length > 1 && bits.length < 9) bits[0] &= mask[bits.length - 1];
12:    array.reverse(bits);
13:    array.resize(ref bits, 8);
14:    if (!bitconverter.islittleendian) array.reverse(bits);
15:    data = decode(bitconverter.toint64(bits, 0));
16:  }

mask 数组其实只需要初始化一次就行了,而不需要每次调用该构造函数时都进行初始化。也就是说,应该将 mask 变量声明为 static 的,如下所示:

static readonly byte[] mask = { 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 };
愿望是美好的,现实是残酷的,加上 static 关键字后,再编译时 c# 编译器会报告以下错误:

error cs0106: 修饰符“static”对该项无效 
也就是说,c# 语言不允许使用 static 修饰符来声明方法内部的变量。但是在 c/c++ 语言中是允许这么做的。

如果把该构造函数内部的 mask 变量提升到构造函数外部,成为 zipinteger 结构的字段成员,就可以声明为 static 的。但是这样一样,读这段代码的人就不容易弄清楚 mask 字段只在这个构造函数内部使用,成为代码的“坏味道”,一点也不优雅了。

 

好了,让我们写一小段程序来测试一下加上 static 后对运行效率的影响:

01:  using system;
02:  using system.io;
03:  using system.diagnostics;
04:  using skyiv.numerics;
05: 
06:  namespace skyiv.tester
07:  {
08:    sealed class statictester
09:    {
10:      static void main()
11:      {
12:        try
13:        {
14:          new statictester().run(100000000);
15:        }
16:        catch (exception ex)
17:        {
18:          console.writeline(ex);
19:        }
20:      }
21: 
22:      void run(int count)
23:      {
24:        console.writeline("  os version: " + environment.osversion);
25:        console.writeline(" clr version: " + environment.version);
26:        using (var reader = new memorystream(getbytes(count)))
27:        {
28:          var watch = stopwatch.startnew();
29:          var n = 0;
30:          for (var i = 0; i < 10; i++)
31:          {
32:            reader.seek(0, seekorigin.begin);
33:            while (zipinteger.read(reader).hasvalue) n++;
34:          }
35:          watch.stop();
36:          console.writeline("       count: " + n.tostring("n0"));
37:          console.writeline("milliseconds: " + watch.elaps教程edmilliseconds.tostring("n0"));
38:        }
39:      }
40: 
41:      byte[] getbytes(int count)
42:      {
43:        var bits = new byte[count];
44:        var rand = new random(123456);
45:        rand.nextbytes(bits);
46:        return bits;
47:      }
48:    }
49:  }
上述程序中第 44 行使用固定的种子初始化 random 类的新实例,从而产生相同的随机数序列,以便用相同的测试用例来进行测试,使测试结果具有可比性。注意,在上述程序中如果 count 值和随机数的种子选取得不好,执行到第 33 行的 zipinteger.read 方法时是有可能抛出 endofstreamexception 异常的。

 

这个测试程序在 windows vista 操作系统的 .net framework 4 环境下的运行结果如下所示:

  os version: microsoft windows nt 6.0.6002 service pack 2
 clr version: 4.0.30319.1
       count: 500,990,730
milliseconds: 181,886

 
将这个测试程序对 mask 变量是非静态的和静态的两种情况分别运行五次,得到的 milliseconds 值如下表所示:

序号 非静态 静态
1 181,886 167,528
2 179,074 166,847
3 180,309 166,526
4 183,542 166,399
5 179,469 167,365
平均 180,856 166,933

经过简单的计算得知,静态情况下比非静态情况下的平均运行效率提高了 7.7%,还是很可观的。

 

这个测试程序在 ubuntu 10.10 操作系统的 mono 2.6.7 环境的运行结果如下所示:

非静态 静态
  os version: unix 2.6.35.24
 clr version: 2.0.50727.1433
       count: 500,992,030
milliseconds: 660,254

   os version: unix 2.6.35.24
 clr version: 2.0.50727.1433
       count: 500,992,030
milliseconds: 583,387

 

首页 1 2 3 末页

时间: 2024-10-31 07:14:38

asp.net C# 中的 static 关键字(1/3)的相关文章

Java中的static关键字解析

static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键字的用法和平常容易误解的地方,最后列举了一些面试笔试中常见的关于static的考题. 以下是本文的目录大纲: 一.static关键字的用途  二.static关键字的误区  三.常见的笔试面试题 一.static关键字的用途   在<Java编程思想>P86页有这样一段话: "static方法就是没有this的方法.在st

C/C++中的static关键字的总结

C/C++中static的2种设计和5种使用方法 面向过程程序设计中的static和面向对象程序设计中的static 具体应用的话,又涉及静态变量和静态函数两类 前者应用于普通变量(变量又分局部变量和全部变量)和函数,不涉及类:后者主要说明static在类中的作用. 因此结构关系如下,那么我们具体来分析 面向过程程序设计中的static 静态局部变量,成为静态局部变量(拥有记忆功能和全局存储权限) 静态全局变量(限制对应全局变量被被其他文件调用) 静态函数 面向对象程序设计中的static. 静

关于C++中的static关键字的总结_C 语言

1.面向过程设计中的static1.1静态全局变量在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量.我们先举一个静态全局变量的例子,如下: 复制代码 代码如下: //Example 1#include <iostream.h>void fn();static int n; //定义静态全局变量void main(){  n=20;  cout<<n<<endl;  fn();} void fn(){ n++;  cout<<n<

Java中的static关键字全面解析_java

static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键字的用法和平常容易误解的地方,最后列举了一些面试笔试中常见的关于static的考题.以下是本文的目录大纲: 一.static关键字的用途 二.static关键字的误区 三.常见的笔试面试题 若有不正之处,希望谅解并欢迎批评指正. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/dolphin05

java 中的static关键字和final关键字的不同之处_java

static 1.在类中,用static修饰的属性,称为静态属性.为这个类的所有对象所共有,存放在静态存储区,所有该类的对象都可以访问且访问的都是同一变量.可以用作计数器,来统计总共创建了多少个各类的对象. 2.在类中,用static 修饰的方法为静态方法,在静态方法中不可以访问非静态的属性和方法,但在非静态方法中可以访问静态方法和属性:且static方法多态失效,不能使用this. 3.由于静态属性和方法是属于该类的所有对象的,所以可以用类名.静态属性/方法名---来访问. 4.static

详解Java编程中static关键字和final关键字的使用_java

Java static关键字以及Java静态变量和静态方法 static 修饰符能够与变量.方法一起使用,表示是"静态"的. 静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员,所以static修饰的成员又称作类变量和类方法.静态变量与实例变量不同,实例变量总是通过对象来访问,因为它们的值在对象和对象之间有所不同. 请看下面的例子: public class Demo { static int i = 10; int j; Demo() { this.j

Java中static关键字的作用和用法详细介绍_java

static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static修饰的成员变量和成员方法独立于该类的任何对象.也就是说,它不依赖类特定的实例,被类的所有实例共享. 只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们.因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象. 用public修饰的static成员变量和成员方法本质是

php中的static

静态成员是一种类变量,可以把它看成时属于整个类而不是属于类的某个实例.与一般的实例变量不同的是,静态成员只保留一个变量值,而这个变量值对所有的实例都是有效的,也就是说,所有的实例共享这个成员. $this只表示类的当前实例,而 self:: 表示的是类本身,在类之外的代码中不能使用这个操作符,而且它不能识别自己在继承树层次结构中的位置.也就是说,在扩展类中使用self 作用域时,self 可以调用基类中声明的方法,但它调用的总是已经在扩展类中重写的方法.与$this不同的是,在使用静态变量时,必

AS 2.0 static 关键字

关键字 static关键字在 ActionScript 2.0 里面也比较重要.如果一个属性是静态的,那么我们可以直接调用-- static(静态)关键字在 ActionScript 2.0 里面也比较重要.如果一个属性是静态的,那么我们可以直接调用,而不用去使用类的Instance 来调用.大部分属性都是要通过类的 Instance 来操作的,那就意味着,它们不是静态的. 例子: // 创建 myClass 的 Instance myInstancemyInstance = new myCla