Try / OpenGothic

Reimplementation of Gothic 2 Notr
MIT License
1.17k stars 85 forks source link

Slow save games - Solution proposal #617

Closed MadShadow- closed 6 months ago

MadShadow- commented 6 months ago

I found a few possibilities to speed up the save game process significantly.

In the serialize class, I changed the compression level from Best Compression to Best Speed. Files sizes are roughly the same, but without the attempts to perfect compression, the saving is a lot faster.

I also reduced the number of files created by collecting all npc and mob data in a respective single file. See npc and vob cpp.

!! This breaks load/save game compatibility to previous versions of course !!

To me my changes look innocent, but I might have introduced bugs. 🐞

Further thoughts

Try commented 6 months ago

Hi, @MadShadow- !

Unfortunately, I have to reject this PR, most of it at least. We can't drop save-game compatibility support - this is strong most reason. While not really specified, but at least 1year old save should be compatible.

I changed the compression level from Best Compression to Best Speed

Is it really faster, or it's side effect of larger files? Can you provide numbers, to illustrate the performance gain?

MadShadow- commented 6 months ago

Is it really faster, or it's side effect of larger files? Can you provide numbers, to illustrate the performance gain?

image

I saved 3 games on each run. Left is MZ_BEST_COMPRESSION and right is MZ_BEST_SPEED. 3 seconds faster on my machine.

gamesession.cpp

void GameSession::save(Serialize &fout, std::string_view name, const Pixmap& screen) {
  SaveGameHeader hdr;
  hdr.version   = Serialize::Version::Current;
  hdr.name      = name;
  hdr.world     = wrld->name();

  using std::chrono::high_resolution_clock;
  using std::chrono::duration_cast;
  using std::chrono::duration;
  using std::chrono::milliseconds;

  auto t1 = high_resolution_clock::now();

  {
  time_t now = std::time(nullptr);
  tm*    tp  = std::localtime(&now);
  hdr.pcTime = *tp;
  }
  hdr.wrldTime  = wrldTime;
  hdr.playTime  = ticks;
  hdr.isGothic2 = Gothic::inst().version().game;

  // [savegame code]

  auto t2 = high_resolution_clock::now();

  /* Getting number of milliseconds as an integer. */
  auto ms_int = duration_cast<milliseconds>(t2 - t1);

  /* Getting number of milliseconds as a double. */
  duration<double, std::milli> ms_double = t2 - t1;

  std::cout << ms_int.count() << "ms\n";
  std::cout << ms_double.count() << "ms\n";
  }