2015-11-05 88 views
0

我正在为.NET平台编写一个非常基本的编译器,并想知道我的常量实现。哪个更快:ldc.i4/ldstr或ldloc?

在我的编译器中,使用常量有望替代ldloc操作。

如果常量theAge(18)和theName(巴里)实际上变量中,IL可能是这样的:

ldstr "Your name is " 
ldloc theName 
concat     //Example operation for concatenating 
ldstr " and you are " 
concat 
ldloc theAge 
tostring    //Example operation for changing the variable to a string 
concat 

但如果我实现了常量:

ldstr "Your name is " 
ldstr "Barry" 
concat 
ldstr " and you are " 
concat 
ldc.i4 18 
tostring 
concat 

这是更快:ldc.i4/ldstr或ldloc?或者,将常量存储为变量会更好吗?

+2

在初始开发期间担心这些细节还为时过早,恕我直言。一旦你有一个实际上可以在任何方面工作的编译器,你可以回头尝试替代代码生成序列,如果你认为它们是合理的,就进行修改。 –

+0

嗯,你正在跳过基本的东西,在你使用LDLOC之前,你首先必须初始化变量。也许与LDSTR。 MSIL和处理器上运行的机器代码之间只有很弱的联系,但是一个非常基本的粗略措施是更多的MSIL需要更多时间来执行。如果变量实际上是用LDSTR初始化的,那么它并不重要,抖动优化器可以轻易地将其删除。 –

回答

2
  1. 我同意@ 500的评论:这是一个微优化,你应该只在你的编译器工作之后担心这个。然后,您应该使用基准来找出哪些选项更快,以及多少,性能难以预测。
  2. 如果我试图预测这一点(尽管我自己的警告如上),我会说直接加载常量会更快(如果差异实际上是可测量的)。

    这是因为在ldc选项中,CPU将读取该指令,然后可以直接将该值写入寄存器。与ldloc,它也会从堆栈中加载值。与ldstr的情况类似。

    但是,如果在局部变量的值是有效恒定的,JIT编译器可以优化ldloc相同的代码ldc,所以可能没有任何差别。 (但我不知道常见的JIT编译器是否可以这样做。)