可能な限り速く1バイトのファイルをファイルからD2アプリケーションに読み込みたい。アプリケーションは1バイトあたりバイトを必要とするため、データの大きなブロックを読み取ることは、リーダーへのインタフェースのオプションではありません。D2のバイトを読み込む最速の方法
このため、私はC++、Java、D2で簡単な実装を作成しました:https://github.com/gizmomogwai/performance。
私が見てきたように、アプリケーションコードとメモリマップされたファイルでプレーンリード、バッファを試しました。 私の用途では、メモリマップされたソリューションがうまく機能しましたが、奇妙なことはD2がjavaよりも遅いということです。私はD2がC++とJava(C++コードは-O3 -gでコンパイルされ、D2コードは-O-releaseでコンパイルされている)の間に置くことを望んでいました。
ここで私が間違っていることと、D2実装をスピードアップする方法を教えてください。あなたがここにユースケースのアイデアを与えることを
は、C++の実装です:
class StdioFileReader {
private:
FILE* fFile;
static const size_t BUFFER_SIZE = 1024;
unsigned char fBuffer[BUFFER_SIZE];
unsigned char* fBufferPtr;
unsigned char* fBufferEnd;
public:
StdioFileReader(std::string s) : fFile(fopen(s.c_str(), "rb")), fBufferPtr(fBuffer), fBufferEnd(fBuffer) {
assert(fFile);
}
~StdioFileReader() {
fclose(fFile);
}
int read() {
bool finished = fBufferPtr == fBufferEnd;
if (finished) {
finished = fillBuffer();
if (finished) {
return -1;
}
}
return *fBufferPtr++;
}
private:
bool fillBuffer() {
size_t l = fread(fBuffer, 1, BUFFER_SIZE, fFile);
fBufferPtr = fBuffer;
fBufferEnd = fBufferPtr+l;
return l == 0;
}
};
size_t readBytes() {
size_t res = 0;
for (int i=0; i<10; i++) {
StdioFileReader r("/tmp/shop_with_ids.pb");
int read = r.read();
while (read != -1) {
++res;
read = r.read();
}
}
return res;
}
Dで「同じ」ソリューションに比べてはるかに高速である:
struct FileReader {
private FILE* fFile;
private static const BUFFER_SIZE = 8192;
private ubyte fBuffer[BUFFER_SIZE];
private ubyte* fBufferPtr;
private ubyte* fBufferEnd;
public this(string fn) {
fFile = std.c.stdio.fopen("/tmp/shop_with_ids.pb", "rb");
fBufferPtr = fBuffer.ptr;
fBufferEnd = fBuffer.ptr;
}
public int read(ubyte* targetBuffer) {
auto finished = fBufferPtr == fBufferEnd;
if (finished) {
finished = fillBuffer();
if (finished) {
return 0;
}
}
*targetBuffer = *fBufferPtr++;
return 1;
}
private bool fillBuffer() {
fBufferPtr = fBuffer.ptr;
auto l = std.c.stdio.fread(fBufferPtr, 1, BUFFER_SIZE, fFile);
fBufferEnd = fBufferPtr + l;
return l == 0;
}
}
size_t readBytes() {
size_t count = 0;
for (int i=0; i<10; i++) {
auto reader = FileReader("/tmp/shop_with_ids.pb");
ubyte buffer[1];
ubyte* p = buffer.ptr;
auto c = reader.read(p);
while (1 == c) {
++count;
c = reader.read(p);
}
}
return count;
}
私はDとJavaで他の関連しないコーディングを行っています(数学的な計算が多い)。そして、Javaはテストで少し速くなっていることが分かりました。私は、あなたが今日Javaをそれほど遅くすることを期待すべきではないと思います.JITコンパイラは最適化に非常に優れています。 –
ええ...あなたは正しい...私はJavaがcppよりもはるかに遅いとは思っていませんが(それはまだデフォルトのjitを使った私のデモの例です)、しかし私のポイントはdがさらに遅いということです。私はdがcppと同等であることを望んだ。 – Gizmomogwai
はい、数ヶ月前にJavaアルゴリズムをDに変換したときもそうでした。私は、彼らはコード最適化を修正するいくつかの癖があると思います。またはGCがちょうど本当に悪いですし、遅いので、それを回してみてください? –