⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 benchmarkdialog.cpp

📁 7z一个高压缩比的压缩程序源代码,重要的是里面的算法值得学习
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  TCHAR s[40];
  {
    UInt64 speed = size * info.GlobalFreq / info.GlobalTime;
    ConvertUInt64ToString(speed / 1024, s);
    lstrcat(s, kKBs);
    SetItemText(speedID, s);
  }
  UInt64 rating;
  if (decompressMode)
    rating = GetDecompressRating(info.GlobalTime, info.GlobalFreq, size, info.PackSize, 1);
  else
    rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, size * info.NumIterations);

  PrintRating(rating, ratingID);
  PrintRating(GetRatingPerUsage(info, rating), rpuID);
  PrintUsage(GetUsage(info), usageID);
}

bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
{
  PrintTime();
  NWindows::NSynchronization::CCriticalSectionLock lock(_syncInfo.CS);

  TCHAR s[40];
  ConvertUInt64ToString((_syncInfo.ProcessedSize >> 20), s);
  lstrcat(s, kMB);
  SetItemText(IDC_BENCHMARK_SIZE_VALUE, s);

  ConvertUInt64ToString(_syncInfo.NumPasses, s);
  SetItemText(IDC_BENCHMARK_PASSES_VALUE, s);

  /*
  ConvertUInt64ToString(_syncInfo.NumErrors, s);
  SetItemText(IDC_BENCHMARK_ERRORS_VALUE, s);
  */

  {
    UInt32 dicSizeTemp = (UInt32)MyMax(_syncInfo.ProcessedSize, UInt64(1) << 20);
    dicSizeTemp = MyMin(dicSizeTemp, _syncInfo.DictionarySize),
    PrintResults(dicSizeTemp,
      _syncInfo.CompressingInfoTemp,
      IDC_BENCHMARK_COMPRESSING_USAGE,
      IDC_BENCHMARK_COMPRESSING_SPEED,
      IDC_BENCHMARK_COMPRESSING_RPU,
      IDC_BENCHMARK_COMPRESSING_RATING);
  }

  {
    PrintResults(
      _syncInfo.DictionarySize,
      _syncInfo.CompressingInfo,
      IDC_BENCHMARK_COMPRESSING_USAGE2,
      IDC_BENCHMARK_COMPRESSING_SPEED2,
      IDC_BENCHMARK_COMPRESSING_RPU2,
      IDC_BENCHMARK_COMPRESSING_RATING2);
  }

  {
    PrintResults(
      _syncInfo.DictionarySize,
      _syncInfo.DecompressingInfoTemp,
      IDC_BENCHMARK_DECOMPRESSING_USAGE,
      IDC_BENCHMARK_DECOMPRESSING_SPEED,
      IDC_BENCHMARK_DECOMPRESSING_RPU,
      IDC_BENCHMARK_DECOMPRESSING_RATING,
      true);
  }
  {
    PrintResults(
      _syncInfo.DictionarySize,
      _syncInfo.DecompressingInfo,
      IDC_BENCHMARK_DECOMPRESSING_USAGE2,
      IDC_BENCHMARK_DECOMPRESSING_SPEED2,
      IDC_BENCHMARK_DECOMPRESSING_RPU2,
      IDC_BENCHMARK_DECOMPRESSING_RATING2,
      true);
    if (_syncInfo.DecompressingInfo.GlobalTime > 0 &&
        _syncInfo.CompressingInfo.GlobalTime > 0)
    {
      UInt64 comprRating = GetCompressRating(_syncInfo.DictionarySize,
          _syncInfo.CompressingInfo.GlobalTime, _syncInfo.CompressingInfo.GlobalFreq, _syncInfo.CompressingInfo.UnpackSize);
      UInt64 decomprRating = GetDecompressRating(_syncInfo.DecompressingInfo.GlobalTime,
          _syncInfo.DecompressingInfo.GlobalFreq, _syncInfo.DecompressingInfo.UnpackSize,
          _syncInfo.DecompressingInfo.PackSize, 1);
      PrintRating((comprRating + decomprRating) / 2, IDC_BENCHMARK_TOTAL_RATING_VALUE);
      PrintRating((
          GetRatingPerUsage(_syncInfo.CompressingInfo, comprRating) +
          GetRatingPerUsage(_syncInfo.DecompressingInfo, decomprRating)) / 2, IDC_BENCHMARK_TOTAL_RPU_VALUE);
      PrintUsage((GetUsage(_syncInfo.CompressingInfo) + GetUsage(_syncInfo.DecompressingInfo)) / 2, IDC_BENCHMARK_TOTAL_USAGE_VALUE);
    }
  }
  return true;
}

bool CBenchmarkDialog::OnCommand(int code, int itemID, LPARAM lParam)
{
  if (code == CBN_SELCHANGE &&
      (itemID == IDC_BENCHMARK_COMBO_DICTIONARY ||
       itemID == IDC_BENCHMARK_COMBO_NUM_THREADS))
  {
    OnChangeSettings();
    return true;
  }
  return CModalDialog::OnCommand(code, itemID, lParam);
}

bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
{
  switch(buttonID)
  {
    case IDC_BUTTON_RESTART:
      OnRestartButton();
      return true;
    case IDC_BUTTON_STOP:
      OnStopButton();
      return true;
  }
  return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
}

struct CThreadBenchmark
{
  CProgressSyncInfo *SyncInfo;
  UInt64 _startTime;
  #ifdef EXTERNAL_LZMA
  CCodecs *codecs;
  #endif
  // UInt32 dictionarySize;
  // UInt32 numThreads;

  HRESULT Process();
  HRESULT Result;
  static THREAD_FUNC_DECL MyThreadFunction(void *param)
  {
    ((CThreadBenchmark *)param)->Result = ((CThreadBenchmark *)param)->Process();
    return 0;
  }
};

struct CBenchCallback: public IBenchCallback
{
  UInt32 dictionarySize;
  CProgressSyncInfo *SyncInfo;
  HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
  HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
};

HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final)
{
  NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
  if (SyncInfo->Changed || SyncInfo->Paused || SyncInfo->Stopped)
    return E_ABORT;
  SyncInfo->ProcessedSize = info.UnpackSize;
  if (final && SyncInfo->CompressingInfo.GlobalTime == 0)
  {
    (CBenchInfo&)SyncInfo->CompressingInfo = info;
    if (SyncInfo->CompressingInfo.GlobalTime == 0)
      SyncInfo->CompressingInfo.GlobalTime = 1;
  }
  else
    (CBenchInfo&)SyncInfo->CompressingInfoTemp = info;

  return S_OK;
}

HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)
{
  NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
  if (SyncInfo->Changed || SyncInfo->Paused || SyncInfo->Stopped)
    return E_ABORT;
  CBenchInfo info2 = info;
  if (info2.NumIterations == 0)
    info2.NumIterations = 1;

  info2.UnpackSize *= info2.NumIterations;
  info2.PackSize *= info2.NumIterations;
  info2.NumIterations = 1;

  if (final && SyncInfo->DecompressingInfo.GlobalTime == 0)
  {
    (CBenchInfo&)SyncInfo->DecompressingInfo = info2;
    if (SyncInfo->DecompressingInfo.GlobalTime == 0)
      SyncInfo->DecompressingInfo.GlobalTime = 1;
  }
  else
    (CBenchInfo&)SyncInfo->DecompressingInfoTemp = info2;
  return S_OK;
}

HRESULT CThreadBenchmark::Process()
{
  try
  {
    SyncInfo->WaitCreating();
    for (;;)
    {
      if (SyncInfo->WasStopped())
        return 0;
      if (SyncInfo->WasPaused())
      {
        Sleep(200);
        continue;
      }
      UInt32 dictionarySize;
      UInt32 numThreads;
      {
        NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
        if (SyncInfo->Stopped || SyncInfo->Paused)
          continue;
        if (SyncInfo->Changed)
          SyncInfo->Init();
        dictionarySize = SyncInfo->DictionarySize;
        numThreads = SyncInfo->NumThreads;
      }
      
      CBenchCallback callback;
      callback.dictionarySize = dictionarySize;
      callback.SyncInfo = SyncInfo;
      HRESULT result;
      try
      {
        result = LzmaBench(
          #ifdef EXTERNAL_LZMA
          codecs,
          #endif
          numThreads, dictionarySize, &callback);
      }
      catch(...)
      {
        result = E_FAIL;
      }

      if (result != S_OK)
      {
        if (result != E_ABORT)
        {
          // SyncInfo->NumErrors++;
          {
            NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
            SyncInfo->Pause();
          }
          CSysString message;
          if (result == S_FALSE)
            message = TEXT("Decoding error");
          else
            message = NError::MyFormatMessage(result);
          MessageBox(0, message, TEXT("7-Zip"), MB_ICONERROR);
        }
      }
      else
      {
        NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
        SyncInfo->NumPasses++;
      }
    }
    // return S_OK;
  }
  catch(CSystemException &e)
  {
    MessageBox(0, NError::MyFormatMessage(e.ErrorCode), TEXT("7-Zip"), MB_ICONERROR);
    return E_FAIL;
  }
  catch(...)
  {
    MyMessageBoxError(0, L"Some error");
    return E_FAIL;
  }
}

HRESULT Benchmark(
  #ifdef EXTERNAL_LZMA
  CCodecs *codecs,
  #endif
  UInt32 numThreads, UInt32 dictionarySize)
{
  CThreadBenchmark benchmarker;
  #ifdef EXTERNAL_LZMA
  benchmarker.codecs = codecs;
  #endif

  CBenchmarkDialog benchmarkDialog;
  benchmarkDialog._syncInfo.DictionarySize = dictionarySize;
  benchmarkDialog._syncInfo.NumThreads = numThreads;

  benchmarker.SyncInfo = &benchmarkDialog._syncInfo;
  NWindows::CThread thread;
  RINOK(thread.Create(CThreadBenchmark::MyThreadFunction, &benchmarker));
  benchmarkDialog.Create(0);
  return thread.Wait();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -