私はロードバランスサーバからファイルをルーチンダウンロードするWindowsアプリケーションを作成しましたが、現在の速度は約30MB /秒です。しかし、FastCopyやTeraCopyを使用しようとすると、約100MB /秒でコピーできます。コピー速度を向上させて、現在よりも高速にファイルをコピーできるようにする方法を知りたい。私のアプリケーションコピーファイルをより速く作る方法
答えて
ストリームを使用する際のよくある間違いの1つは、一度に1バイトずつコピーするか、小さなバッファを使用することです。ディスクにデータを書き込むために必要な時間はほとんどがシークされるので、より大きなバッファを使用するとバイトあたりの平均シーク時間が短縮されます。
オペレーティングシステムはファイルをディスクにディスクに書き込みます。つまり、ディスクに1バイトを書き込むと、実際には512バイトと64 KBの間にブロックが書き込まれます。 64kbの整数倍のバッファを使用すると、ディスクのパフォーマンスを大幅に向上させることができます。
さらに、メモリページサイズの基礎となるCPUの倍数であるバッファを使用することで、ブーストを得ることができます。 x86/x64マシンの場合、これは4kbまたは4mbのいずれかに設定できます。
したがって、4mbの整数倍を使用します。
さらに、非同期IOを使用する場合は、大きなバッファサイズを十分に活用できます。
class Downloader
{
const int size = 4096 * 1024;
ManualResetEvent done = new ManualResetEvent(false);
Socket socket;
Stream stream;
void InternalWrite(IAsyncResult ar)
{
var read = socket.EndReceive(ar);
if (read == size)
InternalRead();
stream.Write((byte[])ar.AsyncState, 0, read);
if (read != size)
done.Set();
}
void InternalRead()
{
var buffer = new byte[size];
socket.BeginReceive(buffer, 0, size, System.Net.Sockets.SocketFlags.None, InternalWrite, buffer);
}
public bool Save(Socket socket, Stream stream)
{
this.socket = socket;
this.stream = stream;
InternalRead();
return done.WaitOne();
}
}
bool Save(System.Net.Sockets.Socket socket, string filename)
{
using (var stream = File.OpenWrite(filename))
{
var downloader = new Downloader();
return downloader.Save(socket, stream);
}
}
おそらく、あなたのアプリケーションが複数のスレッドを使用してファイルを取得するには、マルチスレッド化を行うことができます、しかし、帯域幅がコンテンツを転送するデバイスの速度に制限されている
最も簡単な方法は、生/バイナリでファイルを開くことですモード(thats CはC#と同等のものであるかどうかはっきりしません)、一度に非常に大きなブロック(数MB)を読み書きします。
TeraCopyが使用するトリックは、読み書きを非同期にすることです。これは、別のデータが読み込まれている間にデータのブロックを書き込むことができることを意味します。
あなたの状況に最適なものを得るには、ブロックの数とそれらのブロックのサイズを慎重に検討しなければなりません。私はC++を使ってこの方法を使いました。私たちにとっては、ネットワーク共有からローカルディスクにコピーするときに最適なのは256KBの4つのブロックを使用していました。
よろしく、
Sebastiaan
あなたがProcess Monitorを実行する場合は、WindowsエクスプローラまたはTeraCopyを使用しているブロックサイズを確認することができます。
Vistaでは、ローカルネットワークのデフォルトのブロックサイズは約2MBで、巨大なパイプを介してファイルをより高速にコピーできます。
なぜホイールを改造するのですか?
状況が許せば、既存の「高速」コピーユーティリティの1つに自分自身で書き込みを行うよりも、おそらくもっと良い方法です。処理する必要のある明らかではない多数のエッジケースがあり、常に良好なパフォーマンスを得るには、多くの試行錯誤実験が必要です。
- 1. テセラクトをより速く作る方法
- 2. 私のハッシュアルゴリズムをより速く作る方法
- 3. 私のデータベースからより速く値をロードする方法
- 4. 入れ子のwhileループをより速く作る方法
- 5. DICOMディレクトリをより速く作成する方法は?
- 6. スイングを使用してより速くより速い壁時計を作る方法は?
- 7. openmpコードのパフォーマンスとそれをより速くする方法
- 8. doc2vec - 文書のベクトルをより速く推論する方法
- 9. コードの結果をより速く見る方法
- 10. 特定のマクロをより速く実行する方法
- 11. xmlをより速く読む方法はありますか?
- 12. 再帰関数をより速く実行する方法
- 13. ノードインスペクタでアプリケーションスクリプトをより速く見つける方法は?
- 14. HTMLフォームをより速く構築する方法
- 15. mySQL - ページビューをより速くインクリメントする方法は?
- 16. ASP.net - C# - それをより速く実行する方法ajaxToolkit:ToolkitScriptManager
- 17. PRAGMA synchronous = OFFでSQLiteをより速く実行する方法
- 18. MSVCデバッグビルドをより速く実行する方法
- 19. String.Replace()より速く
- 20. XPath:/ /より速く//?
- 21. カラム指向データベースでディスクシークがより速くなる方法
- 22. 私のコンプレッサーをより速くするための提案
- 23. ラインスペースの0をより速く変更する方法はありますか?
- 24. SQLのクエリをより速く、より良くする
- 25. 私のJavaプログラムをより速く走らせるには?
- 26. Inverse String.Replace - それをより速く行う方法?
- 27. マージソートよりも速く挿入ソートパズル私より
- 28. リアルタイムsocket.ioのポンゲームをより速く作る
- 29. 加重スコアのdata.frameをより速く作成する方法はありますか?
- 30. rack-livereloadをより速く実行する方法はありますか?
スクリプト(コマンドライン)に「高速」コピーユーティリティを使用できますか? – Kiquenet
少なくとも一部はスクリプト可能です - robocopyはその一例です。 – Addys