WinRT:读取和反序列化大量文件需要花费太多时间

时间:2012-12-16 15:26:38

标签: json optimization io windows-runtime

我有一个Windows应用商店应用程序,它管理对象的集合并将它们存储在应用程序本地文件夹中。使用JSON在文件系统上序列化这些对象。由于我需要能够单独编辑和保留这些项目,因此我选择了每个对象的单个文件而不是一个大文件。对象按照以下模式存储:

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序列化对象和其他最终资源。

当我写作,阅读,删除测试时,一切都很好。它变得复杂的是当我试图在应用程序启动时加载大量对象时。我估计第一项的最大数量将存储到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;
}

感谢您的帮助。

注意:我已经看过像SQLite,我不需要这么复杂的系统。

2 个答案:

答案 0 :(得分:1)

据说JSON.NET比内置的东西更好。如果您不是通过网络发送数据,那么最快的方法是进行二进制序列化而不是JSON或XML。最后 - 想想你是否真的需要在应用程序启动时加载所有数据。将数据序列化为二进制记录列表,并创建一个索引,使您可以快速跳转到实际需要使用的记录范围。

答案 1 :(得分:1)

正如Filip已经提到的,您可能不需要在启动时加载所有数据。即使你真的想要显示第一页中的所有项目(一次向用户显示10,000个项目对我来说听起来不是一个好主意),你也不需要提供所有属性:通常只有一个其中几个显示在列表中,当用户导航到单个项目详细信息时,您需要其余部分。您可以拥有一个单独的“索引”文件,其中仅包含列表所需的数据。这确实意味着重复,但它会帮助您提高性能。

虽然你已经提到过,你不需要SQLite,因为它太复杂而不能满足你的需求,你真的应该仔细看看它。它旨在有效地处理您的结构化数据。我很确定如果你切换到它,性能会好得多,而你的代码最终可能会更简单。尝试一下。