Самый быстрый способ чтения байтов в D2

Я хочу как можно быстрее читать отдельные байты из файла в приложение 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;
}

6
задан Gizmomogwai 26 August 2011 в 13:46
поделиться