인터페이스를 명시 적으로 구현할 때 얼마나 많은 비용이 박히는가

StackOverflow https://stackoverflow.com/questions/332803

  •  22-07-2019
  •  | 
  •  

문제

명시적인 회원 구현을위한 현재 가이드 라인은 다음을 권장합니다.

  • 명시 적 멤버를 사용하여 개인 인터페이스 구현을 근사화합니다. 인프라 이유만으로 인터페이스를 구현 해야하는 경우 절대 개발자 가이 유형에서 해당 인터페이스에서 메소드를 직접 호출 할 것을 기대하고 회원을 명시 적으로 구현하여 공개보기에서 '숨기기'.
  • 서브 클래스가 재정의 할 수있는 명시 적으로 구현 된 멤버에 액세스하는 대체 방법을 노출시킵니다.

이것의 좋은 예는 당신이 구현하고 싶을 때입니다. ixmlserializable 상호 작용. 그만큼 readxml 그리고 쓰기 xml 방법은 XMLSerializer에 의해 호출 될 것으로 예상되며 일반적으로 개발자가 직접 호출하지는 않습니다.

명시 적으로 액세스 할 수있는 대안적인 방법을 제공 할 때 재정의를 허용하려는 경우 코드 복제를 피하기 위해 명시 적으로 구현 된 멤버를 호출하는 것이 합리적 인 것 같습니다. 다음을 고려하세요:

using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace Demo
{
    /// <summary>
    /// Demonstrates explicit implementation of the IXmlSerializable interface.
    /// </summary>
    [Serializable(), XmlRoot(ElementName = "foo")]
    public class Foo : IXmlSerializable
    {
        //============================================================
        //  IXmlSerializable Implementation
        //============================================================
        #region GetSchema()
        /// <summary>
        /// Returns an <see cref="XmlSchema"/> that describes the XML representation of the object.
        /// </summary>
        /// <returns>
        /// An <see cref="XmlSchema"/> that describes the XML representation of the object that is 
        /// produced by the <see cref="IXmlSerializable.WriteXml(XmlWriter)"/> method and consumed by the <see cref="IXmlSerializable.ReadXml(XmlReader)"/> method.
        /// </returns>
        /// <remarks>This method is reserved and should not be used.</remarks>
        XmlSchema IXmlSerializable.GetSchema()
        {
            return null;
        }
        #endregion

        #region ReadXml(XmlReader reader)
        /// <summary>
        /// Generates an object from its XML representation.
        /// </summary>
        /// <param name="reader">The <see cref="XmlReader"/> stream from which the object is deserialized.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="reader"/> is a <b>null</b> reference (Nothing in Visual Basic).</exception>
        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            // Class state values read from supplied XmlReader
        }
        #endregion

        #region WriteXml(XmlWriter writer)
        /// <summary>
        /// Converts an object into its XML representation.
        /// </summary>
        /// <param name="writer">The <see cref="XmlWriter"/> stream to which the object is serialized.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="writer"/> is a <b>null</b> reference (Nothing in Visual Basic).</exception>
        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            // Current class state values written using supplied XmlWriter
        }
        #endregion

        //============================================================
        //  Public Methods
        //============================================================
        #region WriteTo(XmlWriter writer)
        /// <summary>
        /// Saves the current <see cref="Foo"/> to the specified <see cref="XmlWriter"/>.
        /// </summary>
        /// <param name="writer">The <see cref="XmlWriter"/> stream to which the <see cref="Foo"/> is serialized.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="writer"/> is a <b>null</b> reference (Nothing in Visual Basic).</exception>
        public void WriteTo(XmlWriter writer)
        {
            writer.WriteStartElement("foo");

            ((IXmlSerializable)this).WriteXml(writer);

            writer.WriteEndElement();
        }
        #endregion
    }
}

내 질문은 쓰기 xml 이 구현에 메소드가 있습니다. ~이다 ((ixmlserializable) this) .writexml (Writer) 성능을 크게 방해할까요?

도움이 되었습니까?

해결책

당신의 예에서는 권투가 일어나지 않습니다 ... 그것은 단지 캐스트 일 뿐이며 컴파일 시간에 해결할 수 있으므로 성능에 전혀 영향을 미치지 않아야합니다.

편집하다: ildasm으로 그것을 살펴보면 인터페이스 캐스트는 가상 메소드 호출 대 정기적 인 메소드 호출을 제공하지만 이는 무시할 수 있습니다 (여전히 권투가 포함되어 있지 않음).

편집 2 : 클래스 대신 구조물을 사용하는 경우 훨씬 더 많은 성능 페널티가있는 인터페이스를 통과하는 상자를 얻게됩니다.

다른 팁

아니요, XMLWriter에게 많은 데이터를 작성하는 데 드는 비용은 복싱 비용을 따돌릴 것입니다.

권투는 다음으로 구성됩니다.

  1. GC에서 메모리 한 조각을 할당합니다
  2. 올바른 유형 정보로 헤더를 초기화합니다
  3. ValueType 데이터를 힙 메모리에 복사합니다

따라서 객체 구성과 거의 같습니다. XMLWriter에 쓰는 단일 데이터조차도 아직 문자열이 아닌 경우, 문자열을 작성하려면 어쨌든이 비용을 지불해야합니다.

명시 적으로 구현 된 인터페이스의 기능을 수행하는 개인 메소드를 호출하게하는 이유는 무엇입니까?

public void IXmlSerializable.WriteXml( XmlWriter writer )
{
    InternalWriteXml( writer );
}

public void WriteTo(XmlWriter writer)
{
    writer.WriteStartElement("foo");

    InternalWriteXml(writer);

    writer.WriteEndElement();
}

private void InternalWriteXml( XmlWriter writer )
{
    ...
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top