我一直非常失望并且收到的申请在某些情况下至少要慢100倍,我必须很快(几周)发布给我们的客户。
通过一些非常简单的分析,我发现瓶颈是它使用.NET Remoting在Windows服务和图形前端之间传输数据 - 两者都运行在同一台机器上。
Microsoft guidelines说“尽量减少往返次数并避免繁琐的接口”:写
MyComponent.SaveCustomer("bob", "smith");
而不是
MyComponent.Firstname = "bob";
MyComponent.LastName = "smith";
MyComponent.SaveCustomer();
我认为这是我们应用程序中问题的根源。不幸的是,调用MyComponent。*(分析器显示99.999%的时间花在这些语句中)在整个源代码中大量分散,我认为没有任何希望根据上述指南重新设计界面。
编辑:事实上,大多数情况下,前端从MyComponent读取属性而不是写入它。但我怀疑MyComponent可以随后在后端进行更改。
我查看是否可以一次性从MyComponent读取所有属性,然后在本地缓存它们(忽略上面任何时候发生的更改),但这将涉及更改数百行代码。
我的问题是:他们是否可以尝试提高绩效的“快速赢家”?
我需要至少100倍的加速。我是一名C / C ++ / Delphi程序员,除了我在过去几天所读到的内容之外,我对C#/ .NET / Remoting非常不熟悉。我正在寻找可以在几天内完成的事情 - 代码的重大重组不是一种选择。
对于初学者,我已经确认它正在使用BinaryFormatter。
(对不起,这可能是一个可怕的问题,如果我排除所有可行的选择,我怎么能切实地修复X ......但我很绝望!)
编辑2 回应理查德在下面的评论:我认为我的问题归结为:
答案 0 :(得分:7)
在.Net Remoting下,您有3种通过HTTP,TCP和IPC进行通信的方式。如果commnuicatin在同一台电脑上,我会使用IPC频道来提升你的通话速度。
答案 1 :(得分:5)
简而言之,这里没有快速的胜利。就个人而言,我不使MyComponent
(作为DTO)成为MarshalByRefObject
(这可能是问题),因为这些往返行程会使你瘫痪。我会将它作为常规类保留,只需移动一些关键方法来抽取它们(即有一个MarshalByRef
manager / repository / etc 类。)
这应该减少往返;如果仍然有问题,那么它可能与带宽相关;这更容易修复;例如,通过更改序列化程序。 protobuf-net允许您通过简单地实现ISerializable
并将两种方法(一种来自界面,加上ctor)转发到ProtoBuf.Serializer
来轻松完成此操作 - 然后它会为您完成所有工作,并且可以正常工作与远程。如果你愿意,我可以提供这方面的例子。
实际上,protobuf-net也可能有助于CPU的使用,因为它是一个更加CPU效率的串行器。
答案 2 :(得分:3)
你能否让MyComponent成为一个缓存值的类,只在调用SaveCustomer()时才提交它们?
答案 3 :(得分:1)
您可以尝试压缩流量。如果不是100倍的增加,你仍然会获得一些性能上的好处
答案 4 :(得分:1)
如果你需要最新的数据(总是看到实际价值),并且每次获取数据的成本占主导地位,那么你需要激进。
如何将轮询更改为推送。而不是每次需要值时调用远程端,远程推送所有更改并在本地缓存最新值。
本地查找(在初始获取之后)始终是最新的,所有远程处理开销都在后台完成(在另一个线程上)。请注意非原子类型的线程安全性。