Ian*_*dby 6 .net c# performance remoting .net-remoting
我已经非常失望并且收到的申请在某些情况下至少要慢100倍,我必须很快(几周)向我们的客户发布.
通过一些非常简单的分析,我发现瓶颈是它使用.NET Remoting在Windows服务和图形前端之间传输数据 - 两者都在同一台机器上运行.
微软的指导方针说"尽量减少往返行程并避免繁琐的接口":写道
MyComponent.SaveCustomer("bob", "smith");
Run Code Online (Sandbox Code Playgroud)
而不是
MyComponent.Firstname = "bob";
MyComponent.LastName = "smith";
MyComponent.SaveCustomer();
Run Code Online (Sandbox Code Playgroud)
我认为这是我们应用程序中问题的根源.不幸的是,调用MyComponent.*(分析器显示99.999%的时间花在这些语句中)在源代码中大量分散,我看不出按照上面的指导方针重新设计界面的任何希望.
编辑:事实上,大多数情况下,前端从MyComponent读取属性而不是写入它.但我怀疑MyComponent可以随后在后端进行更改.
我查看是否可以一次性从MyComponent读取所有属性,然后在本地缓存它们(忽略上面任何时候的更改问题),但这将涉及更改数百行代码.
我的问题是:他们是否可以尝试提高性能的"快速赢家"?
我需要至少100倍的加速.我是一名C/C++/Delphi程序员,除了我在过去几天所读到的内容之外,我对C#/ .NET/Remoting非常不熟悉.我正在寻找可以在几天内完成的事情 - 代码的重大重组不是一种选择.
对于初学者,我已经确认它正在使用BinaryFormatter.
(对不起,这可能是一个可怕的问题,如果我排除所有可行的选择,我怎么能切实修复X ......但我很绝望!)
编辑2 回应理查德的评论如下:我认为我的问题归结为:
简而言之,这里没有快速的胜利.我个人不会做MyComponent(作为DTO)一个MarshalByRefObject(这大概是问题),因为这些往返会削弱你.我会将它保留为常规类,只需移动几个关键方法来抽取它们(即有一个MarshalByRef manager/repository/etc类).
这应该减少往返次数 ; 如果你还有问题那么它可能与带宽有关; 这更容易修复; 例如,通过更改序列化程序.protobuf-net允许您通过简单地实现ISerializable和转发两种方法(一种来自接口,再加上ctor)来轻松完成此操作,ProtoBuf.Serializer然后它可以为您完成所有工作,并且可以使用远程处理.如果你愿意,我可以提供这方面的例子.
实际上,protobuf-net也可能有助于CPU的使用,因为它是一个更高CPU效率的串行器.