gpt4 book ai didi

c# - 在 C# 中加速将复杂类型转换为另一种复杂类型以进行序列化

转载 作者:太空宇宙 更新时间:2023-11-03 17:04:48 24 4
gpt4 key购买 nike

我正在使用 .Net Core 2.1Visual Studio 2017

问题 我正在与第三方合作 dll class未实现 ISerializable 的对象.我正在尝试将这种类型的 4k+ 对象转换为另一种自定义类型,然后将它们序列化以从 API 传回 Web 应用程序。将 1000 个对象转换为可序列化类型大约需要 55 秒,API 返回 JSON 的等待时间总共为 2:30 分钟。 .

我尝试过的 我尝试启动多个任务以将一批 1000 个第 3 方对象转换为自定义可序列化类对象,然后将所有任务结果合并到一个列表中以进行序列化。我试过从使用列表切换到使用数组。我试过使用 Parallel.ForEachConcurrentBag做转换。无论我尝试哪种方式,似乎都需要大约 50 - 60 秒才能将这些对象中的 1000 个转换为自定义可序列化类型。我怀疑其中大部分来自对 new 的调用在第 3 方列表的每次迭代中。我还尝试使用 String Builder 进行字符串连接,通过迭代第 3 方列表并通过连接将属性放入字符串中来创建 JSON 数据结果,这对调用 .ToString() 似乎也很慢

如果有人能在这方面给我一些帮助,我真的很想提高性能时间。我使用 struct 阅读了该内容可能是更好的解决方案,但我还没有尝试过。我希望可能有一种方法可以快速完成此操作并且仍然使用 classes .

代码示例

//OnBaseSearchDocument is my custom class which is serializable
OnBaseSearchDocument[] items = new OnBaseSearchDocument[sizeOfList];

//The class itself
public class OnBaseSearchDocument
{
public string Name { get; set; }

public long DocumentId { get; set; }

public string DocumentType { get; set; }

public string DocStorageDate { get; set; }

public string DocRevisionDate { get; set; }

public string DocumentDate { get; set; }

//Switched to using long for dates so I didn't call .ToString() on DateTimes of 3rd party class
//For the string props above
public long DocDate { get; set; }

public long DocReviseDate { get; set; }

public long DocStoreDate { get; set; }

//Trying to convert
//items is an array of custom class type I created that are serializable
//Hyland.Unity.Document is a 3rd party class contained in a dll - Not Serializable
foreach(Hyland.Unity.Document d in dl)
{
items[counter] = new OnBaseSearchDocument() { DocumentId = d.ID, Name = d.Name, DocumentType = d.DocumentType.Name, DocDate = d.DocumentDate.Ticks, DocReviseDate = d.LatestRevision.Date.Ticks, DocStoreDate = d.DateStored.Ticks };
counter++;
}

编辑

所以,我改用 struct而不是 class :

[Serializable]
public struct StructOnBaseSearchDocument
{
public string Name { get; set; }

public long DocumentId { get; set; }

public string DocumentType { get; set; }

public string DocStorageDate { get; set; }

public string DocRevisionDate { get; set; }

public string DocumentDate { get; set; }
}

for (int i = 0; i < dl.Count; i++)
{
Structs.StructOnBaseSearchDocument st = new Structs.StructOnBaseSearchDocument()
{
DocumentId = dl[i].ID,
Name = dl[i].Name,
DocumentType = dl[i].DocumentType.Name,
DocStorageDate = dl[i].DateStored.ToString(),
DocRevisionDate = dl[i].LatestRevision.Date.ToString(),
DocumentDate = dl[i].DocumentDate.ToString()
};

foundDocs[counter] = st;
counter++;
}

我用秒表来计时转换 - 1000 个 Hyland.Unity.Document 类型的对象转换为自定义 struct在上面的循环中花了 1 分钟。切换到 struct根本没有提高性能。

更新所以,我删除了 Date 的字符串设置和对 .ToString() 的调用。在 DateTimes性能提高了 1000 倍,与调用 .ToString() 时的 1 分钟相比,循环执行时间不到 1 秒。在 DateTime .所以,我想我找到了瓶颈,但我可以在这方面使用一些帮助,因为我仍然需要将这些日期传递回网络应用程序。

更新代码

 //Removed the setting of the string representations of DateTime's in the `struct`
//no calls to `DateTime.ToString()`
for (int i = 0; i < dl.Count; i++)
{
Structs.StructOnBaseSearchDocument st = new Structs.StructOnBaseSearchDocument()
{
DocumentId = dl[i].ID,
Name = dl[i].Name,
DocumentType = dl[i].DocumentType.Name
//DocStorageDate = dl[i].DateStored.ToString(),
//DocRevisionDate = dl[i].LatestRevision.Date.ToString(),
//DocumentDate = dl[i].DocumentDate.ToString()
};

foundDocs[counter] = st;
counter++;
}

最佳答案

(因为我不能发表评论,所以我必须发表建议作为答案)

我认为您首先需要确定的是您的瓶颈究竟在哪里。猜测是在与dl的交互中。也许创建它需要很长时间,或者它可能被懒惰地评估(也就是说,每次通过循环,可能会有一些非常昂贵的调用,这是花费时间的地方)。有几种方法可以查明缓慢的来源: 1. 将一些语句包装在 Stopwatch 中。例如,您可能想要计算具体化每个项目所需的时间。

var sw = Stopwatch();
foreach(Hyland.Unity.Document d in dl)
{
// note: the stop is here intentionally to see how long
// it takes to materialize each item
sw.Stop();
// if this is taking a long time, the bottleneck is (likely)
// in whatever the 3rd party .dll is doing
items[counter] = new OnBaseSearchDocument() { DocumentId = d.ID, Name = d.Name, DocumentType = d.DocumentType.Name, DocDate = d.DocumentDate.Ticks, DocReviseDate = d.LatestRevision.Date.Ticks, DocStoreDate = d.DateStored.Ticks };
counter++;
sw.Start();
}

您还可以包装 OnBaseSearchDocument 的实例化,但如果这是问题所在,我会感到震惊(假设 Hyland.Unity.Document 对象上的属性访问速度很快) 2. 使用分析器(这应该是#1)

关于c# - 在 C# 中加速将复杂类型转换为另一种复杂类型以进行序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58983275/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com