C# 加速复杂类型到另一复杂类型的转换,以便在C中进行序列化

C# 加速复杂类型到另一复杂类型的转换,以便在C中进行序列化,c#,asp.net-core,C#,Asp.net Core,我正在使用.Net Core 2.1和Visual Studio 2017 问题 我使用的是一个第三方dll类对象,它没有实现ISerializable。我正在尝试将这种类型的4k+对象转换为另一种自定义类型,然后将它们序列化,以便从API传递回web应用程序。将1000个对象转换为可序列化类型大约需要55秒,总共需要2:30分钟的等待时间,API才能返回JSON 我试过的 我尝试启动多个任务,将一批1000个第三方对象转换为自定义可序列化类对象,然后将所有任务结果合并到一个列表中进行序列化。我

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

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

我试过的 我尝试启动多个任务,将一批1000个第三方对象转换为自定义可序列化类对象,然后将所有任务结果合并到一个列表中进行序列化。我尝试过从使用列表切换到使用数组。我尝试使用Parallel.ForEach和ConcurrentBag进行转换。无论我采用哪种方式,似乎都需要大约50-60秒才能将1000个对象转换为自定义可序列化类型。我怀疑这大部分来自于第三方列表每次迭代时对new的调用。我还尝试使用字符串生成器进行字符串连接,通过迭代第三方列表并通过连接将属性放入字符串中来创建JSON数据结果,这对调用.ToString来说似乎也非常缓慢

如果有人能在这方面给我一些帮助,我真的很想提高性能。我读到使用struct可能是一个更好的解决方案,但我还没有尝试过。我希望有一种方法可以很快做到这一点,并且仍然使用类

代码示例

}

编辑

因此,我转而使用结构而不是类:


如果你在云中托管,Azure功能可能是理想的。将DLL存储在blob存储中,将DLL转换任务放入队列,然后让Azure函数从队列中使用


你可以很容易地让你的代码同时在数百台机器上运行,一旦任务完成,你就可以停止为它们付费

如果您在云中托管,Azure功能可能是理想的。将DLL存储在blob存储中,将DLL转换任务放入队列,然后让Azure函数从队列中使用


你可以很容易地让你的代码同时在数百台机器上运行,一旦任务完成,你就可以停止为它们付费

因为我不能发表评论,所以我不得不发表建议作为答案

我认为你需要确定的第一件事是你的瓶颈到底在哪里。据猜测,它是在与dl的交互中。可能创建它需要很长时间,或者可能需要惰性地进行评估,也就是说,每次通过循环时,可能会有一些非常昂贵的调用,这就是花费时间的地方。您可以通过以下几种方式确定速度缓慢的原因: 1.用秒表把一些语句包起来。例如,您可能希望确定具体化每个项目所需的时间

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

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

我认为你需要确定的第一件事是你的瓶颈到底在哪里。据猜测,它是在与dl的交互中。可能创建它需要很长时间,或者可能需要惰性地进行评估,也就是说,每次通过循环时,可能会有一些非常昂贵的调用,这就是花费时间的地方。您可以通过以下几种方式确定速度缓慢的原因: 1.用秒表把一些语句包起来。例如,您可能希望确定具体化每个项目所需的时间

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,所以经过一些调查,我发现问题是调用此属性以获取修订日期时间值。这非常奇怪,因为它是一个属性而不是一个方法,所以我真的不明白是什么导致了所有的开销

dl[i].LatestRevision.Date.Ticks, //This is the problem child - apparently calling .LatestRevision
                                 //causes massive overhead, the other two
                                 //DateTimes are no problem at all, loop executes in
                                 //under 1/10th of a second. 
解决方案
我不再麻烦返回最新的修订日期,并将其作为单个调用。如果用户想要查看修订日期,他们会单击一个按钮,调用API并为该特定项返回单个值。案件结案。谢谢大家的意见。

因此,经过一些调查,我发现问题在于调用此属性以获取修订日期时间值。这非常奇怪,因为它是一个属性而不是一个方法,所以我真的不明白是什么导致了所有的开销

dl[i].LatestRevision.Date.Ticks, //This is the problem child - apparently calling .LatestRevision
                                 //causes massive overhead, the other two
                                 //DateTimes are no problem at all, loop executes in
                                 //under 1/10th of a second. 
解决方案 我不再麻烦返回最新的修订日期,如果用户想查看修订日期,我会打一个单独的电话
单击一个按钮,该按钮调用API并返回该特定项的单数值。案件结案。谢谢大家的意见。

你能提供更多关于DLL的信息吗?可能会发布一个示例以及序列化逻辑?@Slothario在评论中添加了示例代码和解释。是否可以使用protobuf之类的东西,或者你是否坚持使用JSON?@Slothario这是我目前的想法,我只是希望有一种方法可以使用我不知道或在研究中没有发现的课程。如果你得到了好的结果,请在这里再次发布,让我知道它是如何进行的!你能提供更多关于DLL的信息吗?可能会发布一个示例以及序列化逻辑?@Slothario在注释中添加了示例代码和解释。是否可以使用protobuf之类的东西,或者你是否坚持使用JSON?@Slothario这是我目前的想法,我只是希望有一种方法可以使用我不知道或在研究中没有发现的课程。如果你得到了好的结果,请在这里再次发布,让我知道它是如何进行的!如果他没有?斯洛塔里奥我不会在云端托管这个。如果他没有?斯洛塔里奥我不会在云端托管这个。
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();
 }
dl[i].LatestRevision.Date.Ticks, //This is the problem child - apparently calling .LatestRevision
                                 //causes massive overhead, the other two
                                 //DateTimes are no problem at all, loop executes in
                                 //under 1/10th of a second.