C# 编译器对局部变量的优化

C# 的编译器可以对代码进行优化,所以,我们在写代码的时候,可以更多地考虑一下代码的易读性问题。

不考虑基本的对齐和换行美化。看一下局部变量优化问题。

C# 示例代码

例如,我们有一段如下的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var s = DoSomething();
Console.WriteLine(s);
} static string DoSomething()
{
var s1 = "Hello, world.";
var s2 = s1.ToUpper();
return s2;
}
}
}

在 DoSomething() 这个方法中,里面定义了两个局部变量:

  • s1
  • s2

在 Main() 方法中,定义了一个局部变量:

  • s

定义 s1 和 s2 是为了提高代码的可读性,它们会导致生成冗余的代码,降低执行效率吗?

我们分别在 Debug 模式下和 Release 模式下进行编译,使用 ILDasm 查看生成的中间代码。

Debug 模式下生成的中间代码

在 Debug 下编译之后,DoSomething() 生成的中间代码如下,可以看到实际上有 3 个局部变量。除了我们自己定义的 s1 和 s2 之外,还有一个生成的 V_2,代码的尺寸为 20。

.method private hidebysig static string  DoSomething() cil managed
{
// Code size 20 (0x14)
.maxstack 1
.locals init ([0] string s1,
[1] string s2,
[2] string V_2)
IL_0000: nop
IL_0001: ldstr "Hello, world."
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: callvirt instance string [mscorlib]System.String::ToUpper()
IL_000d: stloc.1
IL_000e: ldloc.1
IL_000f: stloc.2
IL_0010: br.s IL_0012
IL_0012: ldloc.2
IL_0013: ret
} // end of method Program::DoSomething

看一下 Main() 方法。

有我们定义的 s 这一个局部变量,代码尺寸为 15 个字节。

.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size 15 (0xf)
.maxstack 1
.locals init ([0] string s)
IL_0000: nop
IL_0001: call string ConsoleApp1.Program::DoSomething()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: call void [mscorlib]System.Console::WriteLine(string)
IL_000d: nop
IL_000e: ret
} // end of method Program::Main

Release 模式下生成的中间代码

而在 Release 模式下,实际上,DoSomething() 中所有的局部变量都被优化掉了。代码尺寸也只有 11 个字节。

.method private hidebysig static string  DoSomething() cil managed
{
// Code size 11 (0xb)
.maxstack 8
IL_0000: ldstr "Hello, world."
IL_0005: callvirt instance string [mscorlib]System.String::ToUpper()
IL_000a: ret
} // end of method Program::DoSomething

还可以看一下 Main() 方法,这个局部变量 s 也被优化掉了。代码尺寸也只有 11 字节了。

.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size 11 (0xb)
.maxstack 8
IL_0000: call string ConsoleApp1.Program::DoSomething()
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_000a: ret
} // end of method Program::Main

结论

编译器会尽可能对代码进行优化,我们可以为了提高代码的易读性增加一些局部变量,这并不会导致生成冗余代码并导致执行性能的下降。

C# 编译器对局部变量的优化的更多相关文章

  1. 使用Lua 局部变量来优化性能,同一时候比較局部变量和全局变量

    在竞争激烈的游戏行业中,尤其页游,面对策划复杂和频繁的需求,使用脚本能够减少难度和成本.在使用Lua的过程中,会常常訪问全局变量来作为配置文件. 在訪问全局变量时,能够通过局部变量引用全局变量来优化. ...

  2. vc编译器对 除法的优化

    基本知识,7/2 和 6/2 在计算机中的商都为3.C语言的除法不等同于数学意义中的除法. C语言的除法.采用向零取整的方法. -______________0_______________+ 只有在 ...

  3. Java编译器的2点优化

    优化1 对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(char). 如果没有超过左侧的范围 ...

  4. java9的JShell小工具和编译器两种自动优化

    一.按顺序逐步执行的脚本程序: 二.编译器自动优化 1.不超数据类型范围编译器自动添加强转操作: 2.一但发生运算,byte/short/char都会自动提升为Int,当只有常量参与运算时,编译器会先 ...

  5. 【原创】Java编译器对String的优化

    首先看以下的代码: public static void main(String[] arge) { String str1 = new String("1234"); Strin ...

  6. volatile(防止编译器对代码进行优化)

    adj.易变的:无定性的:无常性的:可能急剧波动的 网络挥发性:挥发性的:不稳定的 volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了.

  7. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part6:Move语义和编译器优化

    本文为第六部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...

  8. 【转】C 编译器优化过程中的 Bug

    C 编译器优化过程中的 Bug 一个朋友向我指出一个最近他们发现的 GCC 编译器优化过程(加上 -O3 选项)里的 bug,导致他们的产品出现非常诡异的行为.这使我想起以前见过的一个 GCC bug ...

  9. JVM性能优化, Part 2 ―― 编译器

    作为JVM性能优化系列文章的第2篇,本文将着重介绍Java编译器,此外还将对JIT编译器常用的一些优化措施进行讨论(参见“JVM性能优化,Part 1″中对JVM的介绍).Eva Andreasson ...

随机推荐

  1. Redis学习(一)认识并安装redis

    一.初识redis Redis是一个开源的Key-Value数据库,通常被称为数据结构服务器,其值可以是多种常见的数据格式,且读写性能极高,且所有操作都是原子性的. Redis是运行在内存中的,但是可 ...

  2. dubbo学习(三)配置dubbo API方式配置

    provider(生产者) import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.Pro ...

  3. 深夜,我偷听到程序员要对session下手……

    我是一个web服务器 我是一个web服务器,我的工作是给人类提供上网服务,我每天要为数以万计的人提供网页浏览服务. 已经是深夜了,我还在和手下几个兄弟为了一件事紧张讨论着. "老大,现在咱们 ...

  4. spark源码分析, 任务反序列化及执行

    1 ==> 接受消息,org.apache.spark.executor.CoarseGrainedExecutorBackend#receive case LaunchTask(data) = ...

  5. linux系统修改不成功/无法修改密码

    1.问题描述 新上架的60台浪潮服务器使用某带外装机平台进行统一安装,安装完成后修改用户密码时统一无法修改,使用root账户无法修改其他用户密码,自身根密码也无法修改成功 2.排查问题 因带外装机平台 ...

  6. mysql-14-transaction

    #TCL /* 事务控制语言 事务:一个或一组sql语句组成一个执行单元,每条sql语句相互依赖 这个执行单元要么全部执行.要么全部失败后回滚 案例:转账 事务的acid属性 1.原子性:事务时一个不 ...

  7. 018 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 12 数据类型转换的基本概念

    018 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 12 数据类型转换的基本概念 本文知识点:Java中的数据类型转换 类型转换 类型转换分类 2类,分别是: ...

  8. lens distortion

    来源:http://michel.thoby.free.fr/Fisheye_history_short/International_Standards_about_Distortion.html H ...

  9. matlab中num2str 将数字转换为字符数组

    参考:https://ww2.mathworks.cn/help/matlab/ref/num2str.html?searchHighlight=num2str&s_tid=doc_srcht ...

  10. SpringBoot 优化