C# のビルドを高速化する

性能の良いSSDが手に入ったので、高速ビルドにチャレンジしてみました。


CPU:Intel Xeon E3-1280 V2 3.6GHz(8core)
Memory:32GB(DDR3)
HDD:Intel SSD 750(Read 2,200MB/s Write 900MB/s)
ソースコード規模:総ステップ 16万行、実ステップ 7万行


MSBuildのオプションは、/m:8 /t:Rebuild


結果は、17.64 Sec
アンチウイルスソフトを止めて再計測、16.04 Sec


CPU性能とSSD性能が、今後劇的に向上するのは考えにくいので、このあたりが限界かもしれませんね。昔のDelphiは、本当に速かったな。

WCF入門-11 App.config以外のファイルからサービス構成を取得する

Sample SourceWCFServer.zip 直


クライアント側は、app.configの場合は、clientbaseを使いますが、別のファイル(例えば、other.config)から設定を読み込む場合は使えません。
ConfigurationManager.OpenMappedExeConfigurationを使ってConfigファイルを読み込んで、ConfigurationChannelFactoryを使ってchannelを作成します。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.Configuration;

namespace WCFInterfaces
{
public class CustomConfigClientBase
{
private ConfigurationChannelFactory _factory = null;
private Lazy _channel = null;

public string CustomConfigFileName { get; set;}
public string CustomEndpointName { get; set;}

private Type CreateChannel()
{
return CreateClientChannel(ref _factory, this.CustomConfigFileName, this.CustomEndpointName);
}

private T CreateClientChannel(ref ConfigurationChannelFactory configChannelFactory,
string configFilePath, string endPointName)
{
var fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configFilePath;
var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
configChannelFactory = new ConfigurationChannelFactory(endPointName, config, null);
return configChannelFactory.CreateChannel();
}

public CustomConfigClientBase()
{
_channel = new Lazy(CreateChannel, true);
}

public Type Channel
{
get{
return _channel.Value;
}
}

public void Close()
{
_factory.Close();
}
}
}

サーバー側は、app.configの場合は、servicehostを使いますが、別のファイルから読み込む場合は、ApplyConfigurationをオーバーライドする手法が使えます。
ApplyConfigurationがコンストラクタで呼び出されてしまうため、別ファイルのファイルパスはクラスのスタティック変数などで渡す必要があります。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.Configuration;

namespace WCFInterfaces
{
public class CustomConfigServiceHost : ServiceHost
{

public static string CustomConfigFileName {get; set;}

public CustomConfigServiceHost(Type serviceType) : base(serviceType)
{
}

protected override void ApplyConfiguration()
{
var filemap = new ExeConfigurationFileMap();
filemap.ExeConfigFilename = CustomConfigServiceHost.CustomConfigFileName;

var config = ConfigurationManager.OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None);
var serviceModel = ServiceModelSectionGroup.GetSectionGroup(config);

bool loaded = false;
foreach (ServiceElement se in serviceModel.Services.Services) {
if (!loaded)
if (se.Name == this.Description.ConfigurationName) {
base.LoadConfigurationSection(se);
loaded = true;
}
}
if (!loaded) {
throw new ArgumentException("Service Element not found in " + CustomConfigServiceHost.CustomConfigFileName);
}

base.ApplyConfiguration();

}

}
}

参照設定に、System.ServiceModelとSystem.Configurationが必要です。

Windows 7 を ルーターにする

Windows 7ルーター化するには以下のレジストリ設定を変更して、ルータ機能を有効にします。


HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
IPEnableRouter
REG_DWORD
1

キーがない場合は追加します。レジストリ設定後にシステムを再起動してください。ルータ化したあとは、通常のルータと同様に扱えるようになるので、別のPCでルータ化したWindows 7デフォルトゲートウェイに設定すればルーティングしてくれるようになります。

C#でMethod全体を排他ロックする

javaのsynchronized相当の機能、c#では属性を指定します。

using System.Runtime.CompilerServices;

[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {
  
  // sync code
  
}

プロパティのget/setにも以下のように指定できます。

public int SyncProperty
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    get { 
        return i; 
    }
    [MethodImpl(MethodImplOptions.Synchronized)]
    set {
        i = value;
    }
}