XML 反序列化嵌入式资源会减慢 Xamarin Forms 中的应用程序启动速度

XML deserializing for embedded resources slow down app startup in Xamarin Forms

我正在使用 Xamarin Forms 为 Android 和 iOS 设备开发移动应用程序。有两个 XML 文件(每个大约 12MB)包含两种语言之间的翻译。目前,这些文件是共享项目中的嵌入式资源,并被反序列化以便在应用程序内部使用。我做了一个(单例)资源管理器来搜索这些文件中的翻译。管理器总是在启动时 运行 一个初始化方法来反序列化 XML 文件并防止在每次应该搜索单词时加载 XML 文件。这会增加启动时间; iOS 在 iPhone 8 上需要 7 秒,在三星 galaxy S8 上 Android 需要 17 秒。

我的问题:

  1. 将这些文件用作共享项目中的嵌入资源是否正确?如果不是,最小化启动的最佳做法是什么?
  2. 读取和反序列化 XML 文件是使用这些文件的最佳方式吗?

请注意,我已经搜索过但没有从经验的角度得出任何结论。任何建议(特别是一些例子)表示赞赏。

更新:

这是 XMl 文件中的示例。但请记住,原始 XML 文件中有超过 50000 个 <word> 标签。

<?xml version="1.0" encoding="utf-8"?>
<MyDictionary>
    <word class="nn" comment="även samklang av andra sinnesintryck; allmänt &amp;quot;överensstämmelse&amp;quot;" lang="sv" value="harmoni">
        <translation comment="also used of harmony of other sensory impressions; generally, &amp;quot;agreement&amp;quot;" value="harmony" />
        <phonetic soundFile="harmoni.swf" value="harmonI:" />
        <paradigm>
            <inflection value="harmonien" />
            <inflection value="harmonier" />
        </paradigm>
        <synonym level="4.4" value="balans" />
        <synonym level="3.2" value="endräkt" />
        <synonym level="3.8" value="samklang" />
        <synonym level="3.3" value="samspel" />
        <synonym level="3.4" value="sämja" />
        <synonym level="3.0" value="välbefinnande" />
        <see type="saldo" value="harmoni||harmoni..1||harmoni..nn.1" />
        <example value="leva i harmoni med naturen">
            <translation value="be at one with Nature" />
        </example>
        <derivation inflection="harmoniskt" value="harmonisk">
            <translation value="harmonious; harmonic" />
        </derivation>
        <definition value="samklang av toner">
            <translation value="the simultaneous combination of musical tones" />
        </definition>
    </word>
</MyDictionary>

为了反序列化,首先使用 Paste Special(将 XML 粘贴为 类) Visual Studio 中的函数。然后使用以下方法执行反序列化。

private MyDictionary Load(string fileName)
{
    try
    {
        var ass = IntrospectionExtensions.GetTypeInfo(typeof(App)).Assembly;
        var resourceName = $"LexinApp.XmlResources.{fileName}";
        using (Stream stream = ass.GetManifestResourceStream(resourceName))
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                var serializer = new XmlSerializer(typeof(MyDictionary));
                return serializer.Deserialize(reader) as MyDictionary;
            }
        }
    }
    catch (Exception) { }

    return null;
}

之后一个词被

搜索
var a = MyDictionary.word.Where(x => x.value == searchKey.ToLower()).ToList();

我最好的猜测是 xml 序列化程序不是同类中最快的,尤其是因为您的词 class 具有一定程度的复杂性。

正如我在评论中所建议的那样,放弃 xml 序列化程序可能会获得相当大的性能提升,编写一个基于 XmlReader 的自定义 xml 解析器并通过它推送数据。

将 xml 的序列化与应用程序的启动时间分离的另一个(或其他)想法是在异步后台任务中加载 xml,这样您的主 UI 就赢了不必等待它,因为你有两个文件,你也可以尝试使用并行线程加载它们(使用 System.Collections.Concurrent):

string[] xmlFileNames = new string[] { "filenameA.xml", "filenameB.xml" };

Parallel.ForEach(xmlFileNames, xmlFile =>
                    {
                        Load(xmlFile);
                    });