[FxCop.性能规则]1. 避免调用需要Unboxing

在Java和C#中,为处理引用和值类型提供灵活性,有Boxing和Unboxing概念。但Unboxing操作会消耗更多系统资源,微软建议尽量避免。调用返回object类型值的函数并转换为值类型会引发Unboxing,可实现强类型方法修复,若无法实现或不关注性能可忽略。

1.     避免调用需要Unboxing

翻译概述:

JavaC#中,所有的数据类型都是从System.Object继承来的,包括数值型类型。这样的设计使我们可以用相同的方式处理引用类型和值类型。从而为我们提供了很大的灵活性,实现更加通用的算法。

但是,将所有数据都放在堆中进行管理无疑会降低程序的性能。因此,C#(包括Java)中都将数据类型分为值类型和引用类型,在常规状态下,值类型局部变量会放在栈中进行管理,从而实现更加高的效率。

这时候就存在将值类型转换为引用类型的问题,因为可能我们的方法只接受引用类型的参数。因此在C#Java中都有BoxingUnboxing的概念。当我们将一个值类型数据复制给一个引用性变量时,会将值类型数据作Boxing处理。在做反向操作时,进行Unboxing处理。相当于作了一个盒子来装这个这类型数据。

但是,正如下文中所说,做Unboxing操作会消耗更多的系统资源,因此,微软建议尽量避免进行Unboxing操作。

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

另外,据说 C# 的范型使用了一定的技术实现了值类型和引用类型同等处理的能力,没有使用 Boxing Unboxing ,因此效率和直接使用强类型方法相当。因此下文中的例子中演示了使用范型替代 ArrayList 来提高效率。

引起的原因:

调用一个返回object类型值得函数,并且将返回值转换为一个值类型。

描述:

将一个object实例转换为之类型会调用Unboxing操作。当调用Unboxing操作时,运行时系统会首先判断这个object实例是否是空引用,然后判断其中存储的数据是不是一个请求类型的数据。如果这两条都满足了,运行时系统会返回一个引用到其中存储的数据,并且将数据从堆中复制到栈中。这些操作会影响执行效率。

修复:

实现一个强类型的方法,并调用这个新方法。如果需要,可以使用范型来实现。

例外:

如果不能实现一个对应的强类型方法,可以忽略这条规则。如果性能并不是关心的重点,可以完全忽略这条规则。

例程:

下面的例子中包含一个方法"WeaklyTyped",这个方法违反了这条规则。例子中还包括另外一个方法”StronglyTyped”,它修正了这个问题。

 

代码见原文

 

下面的例子中包含一个方法”WeaklyTyped”,这个方法违反了这条规则,例子中还包括另外一个方法"UsesGenerics",它使用范型修正了这个问题。

 

代码见原文

 

原文引用:

Avoid calls that require unboxing

TypeName:

AvoidCallsThatRequireUnboxing

CheckId:

CA1808

Category:

Microsoft.Performance

Message Level:

Warning

Certainty:

90%

Breaking Change:

NonBreaking


Cause: A call is made to a method that returns a System.Object instance and the instance is cast to a value type.

Rule Description

Casting an Object instance to a value type invokes an unboxing operation. In an unboxing operation, the runtime first checks whether the instance is null and then determines whether the instance represents the specified value type. If so, the runtime returns a reference to the data portion of the instance and copies the fields from the heap to the stack. These operations degrade performance.

How to Fix Violations

To fix a violation of this rule, replace the call with an equivalent strongly typed method. Use generics if available.

When to Exclude Messages

Exclude a message from this rule if an equivalent strongly typed method is not available. It is also safe to exclude a message from this rule, or ignore the rule entirely, if performance is not a concern.

Example Code

The following example shows a method, WeaklyTyped, which violates the rule and a method, StronglyTyped, which satisfies the rule.

[C#]

None.gif using  System;
None.gif 
None.gif
namespace  PerformanceLibrary
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public interface IWork
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
object DoWork();
ExpandedSubBlockEnd.gif   }

InBlock.gif 
InBlock.gif   
public class Work : IWork
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
object IWork.DoWork()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         
return 3;
ExpandedSubBlockEnd.gif      }

InBlock.gif 
InBlock.gif      
public int DoWork()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         
return 3;
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif   }

InBlock.gif 
InBlock.gif   
public class NeedsWork
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
public void WeaklyTyped()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         IWork iwork 
= new Work();
InBlock.gif 
InBlock.gif         
// The following call violates the rule.
InBlock.gif
         int x = (int)iwork.DoWork();
ExpandedSubBlockEnd.gif      }

InBlock.gif 
InBlock.gif      
public void StronglyTyped()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         Work work 
= new Work();
InBlock.gif         
int x = work.DoWork();
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}

None.gif


The following example shows a method, WeaklyTyped, which violates the rule and a method, UsesGenerics, which satisfies the rule using generics.

[C#]

None.gif using  System;
None.gif
using  System.Collections;
None.gif
using  System.Collections.Generic;
None.gif 
None.gif
namespace  PerformanceLibrary
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public class AvoidBoxing
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
public void WeaklyTyped()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         ArrayList weaklyTypedList 
= new ArrayList();
InBlock.gif         weaklyTypedList.Add(
3);
InBlock.gif         weaklyTypedList.Add(
5);
InBlock.gif         weaklyTypedList.Add(
11);
InBlock.gif 
InBlock.gif         
int sum = 0;
InBlock.gif         
for(int i = 0; i < weaklyTypedList.Count; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif            
// The following call violates the rule.
InBlock.gif
            sum += (int)weaklyTypedList[i];
ExpandedSubBlockEnd.gif         }

ExpandedSubBlockEnd.gif      }

InBlock.gif 
InBlock.gif      
public void UsesGenerics()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         List
<int> stronglyTypedList = new List<int>();
InBlock.gif         stronglyTypedList.Add(
3);
InBlock.gif         stronglyTypedList.Add(
5);
InBlock.gif         stronglyTypedList.Add(
11);
InBlock.gif 
InBlock.gif         
int sum = 0;
InBlock.gif         
for(int i = 0; i < stronglyTypedList.Count; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif            sum 
+= stronglyTypedList[i];
ExpandedSubBlockEnd.gif         }

ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}

None.gif


[Visual Basic]

None.gif Imports  System
None.gif
Imports  System.Collections
None.gif
Imports  System.Collections.Generic
None.gif 
ExpandedBlockStart.gifContractedBlock.gif
Namespace PerformanceLibrary Namespace PerformanceLibrary
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif   
Public Class AvoidBoxingClass AvoidBoxing
InBlock.gif   
ExpandedSubBlockStart.gifContractedSubBlock.gif      
Sub WeaklyTyped()Sub WeaklyTyped()
InBlock.gif      
InBlock.gif         
Dim weaklyTypedList As New ArrayList()
InBlock.gif         weaklyTypedList.Add(
3)
InBlock.gif         weaklyTypedList.Add(
5)
InBlock.gif         weaklyTypedList.Add(
11)
InBlock.gif 
InBlock.gif         
Dim sum As Integer = 0
InBlock.gif         
For I As Integer = 0 To weaklyTypedList.Count - 1
InBlock.gif 
InBlock.gif            
' The following call violates the rule.
InBlock.gif
            sum = sum + DirectCast(weaklyTypedList(I), Integer)
InBlock.gif         
Next
InBlock.gif 
ExpandedSubBlockEnd.gif      
End Sub

InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif      
Sub UsesGenerics()Sub UsesGenerics()
InBlock.gif      
InBlock.gif         
Dim stronglyTypedList As New List(Of Integer)
InBlock.gif         stronglyTypedList.Add(
3)
InBlock.gif         stronglyTypedList.Add(
5)
InBlock.gif         stronglyTypedList.Add(
11)
InBlock.gif 
InBlock.gif         
Dim sum As Integer = 0
InBlock.gif         
For I As Integer = 0 To stronglyTypedList.Count - 1
InBlock.gif            sum 
= sum + DirectCast(stronglyTypedList(I), Integer)
InBlock.gif         
Next
InBlock.gif 
ExpandedSubBlockEnd.gif      
End Sub

InBlock.gif 
ExpandedSubBlockEnd.gif   
End Class

InBlock.gif 
ExpandedBlockEnd.gif
End Namespace

None.gif

 

转载于:https://www.cnblogs.com/Cajon/archive/2005/08/10/211946.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值