2012-12-16 2 views
0

개체 컬렉션을 관리하고 응용 프로그램 로컬 폴더에 저장하는 Windows 저장소 응용 프로그램이 있습니다. 이러한 객체는 JSON을 사용하여 파일 시스템에서 직렬화됩니다. 이러한 항목을 개별적으로 편집하고 유지할 수 있어야하므로 하나의 큰 파일 대신 각 개체의 개별 파일을 선택했습니다. 객체는이 패턴 다음 저장됩니다WinRT : 많은 양의 파일을 읽고 병렬 처리하는 데 너무 많은 시간이 걸립니다.

Local Folder 
| 
--- db 
    | 
    --- AB283376-7057-46B4-8B91-C32E663EC964 
    | | 
    | --- AB283376-7057-46B4-8B91-C32E663EC964.json 
    | --- AB283376-7057-46B4-8B91-C32E663EC964.jpg 
    | 
    --- B506EFC5-E853-45E6-BA32-64193BB49ACD 
    | | 
    | --- B506EFC5-E853-45E6-BA32-64193BB49ACD.json 
    | --- B506EFC5-E853-45E6-BA32-64193BB49ACD.jpg 
    | 
    ... 

각 객체 의지가 JSON 직렬화 된 객체 및 기타 최종 리소스가 포함되어 그 폴더 노드가 있습니다.

필자가 쓰기, 읽기, 삭제 테스트를 할 때 모든 것이 잘되었습니다. 복잡하게 된 부분은 응용 프로그램 시작시 대량의 객체 모음을로드하려고 할 때입니다. 나는 항목 1의 가장 큰 금액이 10000으로 저장할 것이라고 예상했다. 그래서 나는 10000 개의 항목을 쓴 다음 그것을로드하려고 시도했다. 응용 프로그램을 완료하는 데 3 분 이상 걸렸는데 물론 받아 들일 수 없다.

그럼 내 질문은 다음과 같습니다. 개체를 읽고 역 직렬화하기 위해 만든 코드에서 무엇이 최적화 될 수 있습니까? 페이징 시스템을 구현하여 내 WinRT 응용 프로그램에서 동적으로로드되도록하는 방법이 있습니까? 내 저장 방법 (위의 패턴)이 IO/CPU의 측면에서 너무 무겁습니까? WinRT에서 뭔가 빠졌습니까?

public async Task<IEnumerable<Release>> GetReleases() 
{ 
    List<Release> items = new List<Release>(); 

    var dbFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(dbName, CreationCollisionOption.OpenIfExists); 

    foreach (var releaseFolder in await dbFolder.GetFoldersAsync()) 
    { 
     var releaseFile = await releaseFolder.GetFileAsync(releaseFolder.DisplayName + ".json"); 
     var stream = await releaseFile.OpenAsync(FileAccessMode.Read); 

     using (var inStream = stream.GetInputStreamAt(0)) 
     { 
      DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Release)); 
      Release release = (Release)serializer.ReadObject(inStream.AsStreamForRead()); 
      items.Add(release); 
     } 

     stream.Dispose(); 
    } 

    return items; 
} 

도움 주셔서 감사합니다.

NB : 이미 SQLite로 보였으 나 이러한 정교한 시스템이 필요하지 않습니다.

답변

1

아마도 JSON.NET은 기본 제공되는 것보다 낫습니다. 유선을 통해 데이터를 전송하지 않는다면 가장 빠른 방법은 JSON 또는 XML 대신 바이너리 직렬화를 수행하는 것입니다. 마지막으로, 응용 프로그램이 시작될 때 모든 데이터를 실제로로드해야한다고 생각하십시오. 바이너리 레코드 목록으로 데이터를 직렬화하고 실제로 사용해야하는 레코드 범위로 빠르게 이동할 수있는 인덱스를 만듭니다.

+0

WinRT에서 사용할 수있는 바이너리 직렬화가 없다고합니다. 나는 이것을지지하는 도서관을 찾으려고 노력할 것이다. Json.Net을 테스트 한 결과 로딩시 20 %의 성능 향상을 보았습니다. 따라서 매우 고무적이었습니다! 나는 데이터베이스와 같이 개별적으로 작성 될 수 있기 때문에 내 객체의 원 자성과 비슷합니다. 목록에 직렬화하면 파일 시스템 IO 오버 헤드가 조금씩 제거되지만 직렬화에서는 더 빨리 수행되지 않습니다. – Ucodia

1

이미 언급했듯이, 시작할 때 모든 데이터를로드 할 필요는 없습니다. 첫 번째 페이지에 모든 항목을 표시하려고한다고해도 (사용자에게 한꺼번에 10,000 개의 항목을 표시하는 것이 나에게 좋은 생각 인 것은 아님) 모든 속성을 사용할 필요는 없습니다. 일반적으로 그 중 몇 개가 목록에 표시되면 사용자가 개별 항목 세부 정보로 이동할 때 나머지 부분이 필요합니다. 목록에 필요한 데이터 만 포함 된 별도의 "색인"파일을 가질 수 있습니다. 이는 중복을 의미하지만 성능 향상에 도움이됩니다.

비록 언급했지만 SQLite는 사용자의 요구에 너무 정교하기 때문에 필요하지 않습니다. 실제로 자세히 살펴 봐야합니다. 그것은 당신과 같은 구조화 된 데이터를 효율적으로 처리하도록 설계되었습니다. 나는 당신이 그것을 바꾼다면 성능이 훨씬 좋아질 것이고 결국 코드가 더 단순해질 수도 있다는 것을 확신한다. 그것을 밖으로 시도하십시오.

+0

실제로 시작할 때 모든 것을로드 할 필요가 없기 때문에 페이징을 제안했습니다. WinRT가 특정 웹 서비스의 페이징 기능 덕분에로드 된 가상화 된 목록을 제공한다고 들었지만 자체 데이터 소스를 제공하고 있기 때문에 구현 방법을 알지 못합니다. SQLite의 경우 객체 모델은 매우 간단하며 열거 형을 참조하는 목록을 포함합니다.객체 모델은 SQLite를 사용하면 훨씬 더 복잡해 질 것입니다. 직렬화를 사용해도 걱정할 필요는 없지만 쿼리 가능한 데이터 소스를 사용하면 좋을 것이라고 거짓말을 할 수는 없습니다. – Ucodia

관련 문제