void benchrenderpage(fz_context *ctx, pdf_document *xref, pdf_page *page, int pagenum) { fz_device *dev; fz_pixmap *pix; fz_bbox bbox; mstimer timer; timerstart(&timer); bbox = fz_round_rect(pdf_bound_page(xref, page)); pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, bbox); fz_clear_pixmap_with_value(ctx, pix, 0xFF); dev = fz_new_draw_device(ctx, pix); fz_try(ctx) { pdf_run_page(xref, page, dev, fz_identity, NULL); timerstop(&timer); logbench("pagerender %3d: %.2f ms\n", pagenum, timeinms(&timer)); } fz_catch(ctx) { logbench("Error: pdf_run_page() failed\n"); } fz_drop_pixmap(ctx, pix); fz_free_device(dev); }
static void BenchLoadRender(BaseEngine *engine, int pagenum) { Timer t(true); bool ok = engine->BenchLoadPage(pagenum); t.Stop(); if (!ok) { logbench("Error: failed to load page %d", pagenum); return; } double timems = t.GetTimeInMs(); logbench("pageload %3d: %.2f ms", pagenum, timems); t.Start(); RenderedBitmap *rendered = engine->RenderBitmap(pagenum, 1.0, 0); t.Stop(); if (!rendered) { logbench("Error: failed to render page %d", pagenum); return; } delete rendered; timems = t.GetTimeInMs(); logbench("pagerender %3d: %.2f ms", pagenum, timems); }
static void BenchFile(const WCHAR *filePath, const WCHAR *pagesSpec) { if (!file::Exists(filePath)) { return; } // ad-hoc: if enabled times layout instead of rendering and does layout // using all text rendering methods, so that we can compare and find // docs that take a long time to load if (Doc::IsSupportedFile(filePath) && !gGlobalPrefs->ebookUI.useFixedPageUI) { BenchEbookLayout(filePath); return; } if (ChmModel::IsSupportedFile(filePath) && !gGlobalPrefs->chmUI.useFixedPageUI) { BenchChmLoadOnly(filePath); return; } Timer total; logbench(L"Starting: %s", filePath); Timer t; BaseEngine *engine = EngineManager::CreateEngine(filePath); if (!engine) { logbench(L"Error: failed to load %s", filePath); return; } double timeMs = t.Stop(); logbench(L"load: %.2f ms", timeMs); int pages = engine->PageCount(); logbench(L"page count: %d", pages); if (nullptr == pagesSpec) { for (int i = 1; i <= pages; i++) { BenchLoadRender(engine, i); } } assert(!pagesSpec || IsBenchPagesInfo(pagesSpec)); Vec<PageRange> ranges; if (ParsePageRanges(pagesSpec, ranges)) { for (size_t i = 0; i < ranges.Count(); i++) { for (int j = ranges.At(i).start; j <= ranges.At(i).end; j++) { if (1 <= j && j <= pages) BenchLoadRender(engine, j); } } } delete engine; total.Stop(); logbench(L"Finished (in %.2f ms): %s", total.GetTimeInMs(), filePath); }
void benchfile(char *pdffilename, int loadonly, int pageNo) { pdf_document *xref = NULL; mstimer timer; int page_count; int curpage; fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT); if (!ctx) { logbench("Error: fz_new_context() failed\n"); return; } logbench("Starting: %s\n", pdffilename); timerstart(&timer); fz_var(xref); fz_try(ctx) { xref = openxref(ctx, pdffilename); } fz_catch(ctx) { goto Exit; } timerstop(&timer); logbench("load: %.2f ms\n", timeinms(&timer)); page_count = pdf_count_pages(xref); logbench("page count: %d\n", page_count); if (loadonly) goto Exit; for (curpage = 1; curpage <= page_count; curpage++) { pdf_page *page; if ((-1 != pageNo) && (pageNo != curpage)) continue; page = benchloadpage(ctx, xref, curpage); if (page) { benchrenderpage(ctx, xref, page, curpage); pdf_free_page(xref, page); } } Exit: logbench("Finished: %s\n", pdffilename); pdf_close_document(xref); fz_free_context(ctx); }
static int TimeOneMethod(Doc&doc, TextRenderMethod method, const WCHAR *methodName) { SetTextRenderMethod(method); Timer t; int nPages = FormatWholeDoc(doc); double timesms = t.Stop(); logbench(L"%s: %.2f ms", methodName, timesms); return nPages; }
static void BenchFile(TCHAR *filePath, const TCHAR *pagesSpec) { if (!file::Exists(filePath)) { return; } Timer total(true); logbench("Starting: %s", filePath); Timer t(true); BaseEngine *engine = EngineManager(!gUseEbookUI).CreateEngine(filePath); t.Stop(); if (!engine) { logbench("Error: failed to load %s", filePath); return; } double timems = t.GetTimeInMs(); logbench("load: %.2f ms", timems); int pages = engine->PageCount(); logbench("page count: %d", pages); if (NULL == pagesSpec) { for (int i = 1; i <= pages; i++) { BenchLoadRender(engine, i); } } assert(!pagesSpec || IsBenchPagesInfo(pagesSpec)); Vec<PageRange> ranges; if (ParsePageRanges(pagesSpec, ranges)) { for (size_t i = 0; i < ranges.Count(); i++) { for (int j = ranges.At(i).start; j <= ranges.At(i).end; j++) { if (1 <= j && j <= pages) BenchLoadRender(engine, j); } } } delete engine; total.Stop(); logbench("Finished (in %.2f ms): %s", total.GetTimeInMs(), filePath); }
pdf_page *benchloadpage(fz_context *ctx, pdf_document *xref, int pagenum) { pdf_page *page = NULL; mstimer timer; timerstart(&timer); fz_try(ctx) { page = pdf_load_page(xref, pagenum - 1); } fz_catch(ctx) { logbench("Error: failed to load page %d\n", pagenum); return NULL; } timerstop(&timer); logbench("pageload %3d: %.2f ms\n", pagenum, timeinms(&timer)); return page; }
static void BenchChmLoadOnly(const WCHAR* filePath) { Timer total; logbench(L"Starting: %s", filePath); Timer t; ChmModel* chmModel = ChmModel::Create(filePath, nullptr); if (!chmModel) { logbench(L"Error: failed to load %s", filePath); return; } double timeMs = t.Stop(); logbench(L"load: %.2f ms", timeMs); delete chmModel; total.Stop(); logbench(L"Finished (in %.2f ms): %s", total.GetTimeInMs(), filePath); }
void BenchFileOrDir(WStrVec& pathsToBench) { gLog = new slog::StderrLogger(); size_t n = pathsToBench.size() / 2; for (size_t i = 0; i < n; i++) { WCHAR* path = pathsToBench.at(2 * i); if (file::Exists(path)) BenchFile(path, pathsToBench.at(2 * i + 1)); else if (dir::Exists(path)) BenchDir(path); else logbench(L"Error: file or dir %s doesn't exist", path); } delete gLog; }
pdf_document *openxref(fz_context *ctx, char *filename) { pdf_document *xref = pdf_open_document(ctx, filename); fz_try(ctx) { if (pdf_needs_password(xref)) { logbench("Warning: password protected document\n"); fz_throw(ctx, "document requires password"); } pdf_count_pages(xref); } fz_catch(ctx) { pdf_close_document(xref); fz_rethrow(ctx); } return xref; }
// this is to compare the time it takes to layout a whole ebook file // using different text measurement method (since the time is mostly // dominated by text measure) void BenchEbookLayout(const WCHAR *filePath) { bool deleteLog = false; if (!gLog) { gLog = new slog::StderrLogger(); deleteLog = true; } logbench(L"Starting: %s", filePath); if (!file::Exists(filePath)) { logbench(L"Error: file doesn't exist"); return; } if (!Doc::IsSupportedFile(filePath)) { logbench(L"Error: not an ebook file"); return; } Timer t; Doc doc = Doc::CreateFromFile(filePath); if (doc.LoadingFailed()) { logbench(L"Error: failed to load the file as doc"); doc.Delete(); return; } double timeMs = t.Stop(); logbench(L"load: %.2f ms", timeMs); int nPages = TimeOneMethod(doc, TextRenderMethodGdi, L"gdi "); TimeOneMethod(doc, TextRenderMethodGdiplus, L"gdi+ "); TimeOneMethod(doc, TextRenderMethodGdiplusQuick, L"gdi+ quick"); // do it twice because the first run is very unfair to the first version that runs // (probably because of font caching) TimeOneMethod(doc, TextRenderMethodGdi, L"gdi "); TimeOneMethod(doc, TextRenderMethodGdiplus, L"gdi+ "); TimeOneMethod(doc, TextRenderMethodGdiplusQuick, L"gdi+ quick"); doc.Delete(); logbench(L"pages: %d", nPages); if (deleteLog) { delete gLog; } }