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


    1.     避免调用需要Unboxing

    翻译概述:

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

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

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

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

     另外,据说C#的范型使用了一定的技术实现了值类型和引用类型同等处理的能力,没有使用BoxingUnboxing,因此效率和直接使用强类型方法相当。因此下文中的例子中演示了使用范型替代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#]

    using System;
     
    namespace PerformanceLibrary
    {
       
    public interface IWork
       
    {
          
    object DoWork();
       }

     
       
    public class Work : IWork
       
    {
          
    object IWork.DoWork()
          
    {
             
    return 3;
          }

     
          
    public int DoWork()
          
    {
             
    return 3;
          }

       }

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

     
          
    public void StronglyTyped()
          
    {
             Work work 
    = new Work();
             
    int x = work.DoWork();
          }

       }

    }


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

    [C#]

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

          }

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

          }

       }

    }


    [Visual Basic]

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

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

     
       
    End Class

     
    End Namespace

     

  • 相关阅读:
    如何找出一个数组中第二大的数
    如何把一个整型数组中重复的数字去掉
    假设数组a有n个元素,元素取值范围是1~n,如何判定数组是否存在重复元素
    如何重新排列数组使得数组左边为奇数,右边为偶数,并使得空间复杂度为O(1),时间复杂度为O(n)
    给一个由n-1个整数组成的未排序的序列,其元素都是1~n中的不同的整数。如何在线性时间复杂度内寻找序列中缺失的整数
    已知大小分别为m、n的两个无序数组A、B和一个常数c,求满足A[i]+B[j]=c的所有A[i]和B[j]
    如何找出数组中符合条件的数对
    如何找出数组中出现奇数次的元素
    云服务器ECS挖矿木马病毒处理和解决方案
    Java下载https文件上传到阿里云oss服务器
  • 原文地址:https://www.cnblogs.com/Cajon/p/211946.html
Copyright © 2020-2023  润新知