Windows では問題なく動作するシンプルな WCF ホストとクライアントがありますが、Mono 2.10.8/9 ではパフォーマンスが非常に悪くなります。
WCF ホストは、セルフホステッド コンソール アプリで実行されています。WCF クライアントもシンプルなコンソール アプリです。セキュリティなしで netTcpBinding を使用しています。
ホスト app.config は次のとおりです。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MetadataBehavior">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MetadataBehavior" name="EmployeeServiceLib.EmployeeService">
<clear />
<endpoint address="net.tcp://localhost:8888/EmployeeService/tcp"
binding="netTcpBinding" bindingConfiguration="ultra" name="EmployeeService"
contract="EmployeeServiceLib.IEmployeeService" listenUriMode="Explicit" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="ultra" transactionFlow="false" transferMode="Streamed">
<reliableSession enabled="false" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
クライアント app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="EmployeeService" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
transferMode="Streamed" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="65536" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="1048576">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8888/EmployeeService/tcp"
binding="netTcpBinding" bindingConfiguration="EmployeeService"
contract="EmployeeService.IEmployeeService" name="EmployeeService" />
</client>
</system.serviceModel>
</configuration>
WCF サービス クラス:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single,
AddressFilterMode = AddressFilterMode.Any)]
public class EmployeeService : IEmployeeService
{
private readonly List<Employee> m_Employees = new List<Employee>();
#region IEmployeeService Members
public void AddEmployee(Employee employee)
{
m_Employees.Add(employee);
}
// ... snipped ...
}
クライアントが行うことは、OperationContract を 100 回呼び出し、呼び出しをベンチマークすることです。
var employee = new Employee { ... };
var client = new EmployeeServiceClient("EmployeeService", "net.tcp://localhost:8888/EmployeeService/tcp");
client.Open();
Console.Write("Adding 100 employees...");
var startTime = Environment.TickCount;
for (int i = 0; i < 100; i++)
{
client.AddEmployee(employee);
}
var timeTaken = Environment.TickCount - startTime;
Console.WriteLine(" Done.");
ベンチマーク結果:
.NET 4.0 = 62 ミリ秒
モノ 2.11.1 = 1672 ミリ秒
VM で実行されている Debian 6 の Mono 2.10.9 = 9632 ミリ秒 (CPU 使用率は約 1% で推移)
Debian の Mono esp で WCF のパフォーマンスを高速化するにはどうすればよいですか?