programing

Json은 그렇다.NET 캐시 유형의 시리얼화 정보

lastmoon 2023. 3. 13. 20:45
반응형

Json은 그렇다.NET 캐시 유형의 시리얼화 정보

.NET 월드에서는 일반적으로 오브젝트 시리얼라이제이션에 관해 런타임에 오브젝트의 필드와 속성을 검사합니다.이 작업에 리플렉션을 사용하는 것은 보통 느리고 큰 개체 집합을 처리할 때는 바람직하지 않습니다.또 다른 방법은 IL 방출을 사용하거나 반사에 비해 상당한 성능 향상을 제공하는 표현 트리를 구축하는 것입니다.그리고 후자는 연재를 다룰 때 대부분의 현대 도서관이 꼽는 것입니다.그러나 실행 시 IL을 구축하여 내보내는 데는 시간이 걸리며, 이 정보가 캐시되어 동일한 유형의 개체에 재사용되는 경우에만 투자가 회수됩니다.

Json을 사용할 때.NET, 위에서 설명한 방법이 어떤 것인지, 그리고 후자가 실제로 사용되는지, 캐싱이 사용되는지는 명확하지 않습니다.

예를 들어, 다음과 같이 합니다.

JsonConvert.SerializeObject(new Foo { value = 1 });

Json은 그렇다.NET은 Foo의 멤버 액세스 정보와 캐시를 구축하여 나중에 재사용할 수 있습니까?

네, 그렇습니다.Json.NET은 클래스 내에 유형 일련화 정보를 캐시합니다. 사용자 정의 계약 해결 프로그램을 지정하지 않는 한 이 정보는 캐시되고 재사용됩니다.

위해서DefaultContractResolver글로벌 스태틱인스턴스는 그 Json 내부적으로 유지됩니다.NET은 응용 프로그램이 자체 계약 해결사를 지정하지 않을 때마다 사용합니다. CamelCasePropertyNamesContractResolver한편, 는 모든 인스턴스에서 공유되는 스태틱테이블을 유지합니다.(이러한 불일치는 레거시 문제에서 기인한다고 생각합니다.자세한 내용은 여기를 참조하십시오.)

이러한 타입은 모두 스레드 세이프가 완전히 적용되도록 설계되어 있기 때문에 스레드간의 공유는 문제가 되지 않습니다.

자체 계약 해결사를 구현하고 인스턴스화하도록 선택한 경우 유형 정보는 계약 해결사 인스턴스 자체를 캐시하고 재사용하는 경우에만 캐시되고 재사용됩니다.따라서 Newtonsoft는 다음을 권장합니다.

성능을 위해 계약 해결사를 한 번 생성하고 가능한 경우 인스턴스를 재사용해야 합니다.계약 해결은 느리고 IContractResolver의 구현은 일반적으로 계약을 캐시합니다.

메모리 소비가 문제이고 캐시된 계약에 의해 영구적으로 사용되는 메모리를 최소화할 필요가 있는 경우 로컬 인스턴스를 직접 구축할 수 있습니다.DefaultContractResolver(또는 일부 커스텀서브클래스)를 사용하여 시리얼화한 후 해당 서브클래스에 대한 모든 참조를 즉시 삭제합니다.예를 들어 다음과 같습니다.

public class JsonExtensions
{
    public static string SerializeObjectNoCache<T>(T obj, JsonSerializerSettings settings = null)
    {
        settings = settings ?? new JsonSerializerSettings();
        bool reset = (settings.ContractResolver == null);
        if (reset)
            // To reduce memory footprint, do not cache contract information in the global contract resolver.
            settings.ContractResolver = new DefaultContractResolver();
        try
        {
            return JsonConvert.SerializeObject(obj, settings);
        }
        finally
        {
            if (reset)
                settings.ContractResolver = null;
        }
    }
}

그리고 만약 당신이 그것을 사용하고 있다면CamelCasePropertyNamesContractResolver로.DefaultContractResolver다음과 같은 적절한 명명 전략을 사용합니다.

settings.ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() };

캐시된 계약 메모리의 대부분(전부는 아님)은 최종적으로 가비지가 수집됩니다.물론 이렇게 하면 시리얼라이제이션 퍼포먼스가 크게 저하될 수 있습니다.(일부 테이블에는 에 대한 정보가 반영되어 있습니다. enum유형 및 데이터 계약 속성은 글로벌하게 공유되며 재확보되지 않습니다.)

자세한 내용은 Newtonsoft의 "퍼포먼스 팁: 재이용 계약 해결사"를 참조하십시오.

언급URL : https://stackoverflow.com/questions/33557737/does-json-net-cache-types-serialization-information

반응형