在D2中读取字节的最快方法

Giz*_*wai 6 c++ d

我想尽可能快地从文件读取单个字节到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;
}
Run Code Online (Sandbox Code Playgroud)

与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;
}
Run Code Online (Sandbox Code Playgroud)

Meh*_*dad 3

很有可能是因为sfread。没有人保证它在 D 中和在 C 中做同样的事情——您很可能完全使用不同的 CRT(除非您使用的是 Digital Mars C++ 编译器?)。

这意味着库可能会执行同步等操作,从而降低速度。您知道的唯一方法是通过告诉链接器链接到相同的库来强制D 使用与 C 相同的库。

在你能做到这一点之前,你就是在将苹果与橙子进行比较。如果这是不可能的,那么直接从两者调用操作系统,然后比较结果——这样就可以保证两者的底层调用是相同的。