From 5737bdb3d7e5819528e33c360a73372e0e93a6be Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Fri, 3 Nov 2023 12:04:30 +0000 Subject: [PATCH] speed up hunspell inner loop which calls into the kernel to get elapsed time, instead of using the VDSO-based CLOCK_MONOTONIC (or at least, the C++ equivalent of that), which is much faster https://gerrit.libreoffice.org/c/core/+/158809 --- src/hunspell/affixmgr.cxx | 43 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/hunspell/affixmgr.cxx b/src/hunspell/affixmgr.cxx index 2cad09f..a3c93cd 100644 --- a/src/hunspell/affixmgr.cxx +++ b/src/hunspell/affixmgr.cxx @@ -75,6 +75,7 @@ #include #include +#include #include #include #include @@ -1590,17 +1591,20 @@ struct hentry* AffixMgr::compound_check(const std::string& word, // add a time limit to handle possible // combinatorical explosion of the overlapping words - HUNSPELL_THREAD_LOCAL clock_t timelimit; + HUNSPELL_THREAD_LOCAL std::chrono::steady_clock::time_point clock_time_start; + HUNSPELL_THREAD_LOCAL bool timelimit_exceeded; + + // get the current time + std::chrono::steady_clock::time_point clock_now = std::chrono::steady_clock::now(); if (wordnum == 0) { - // get the start time, seeing as we're reusing this set to 0 - // to flag timeout, use clock() + 1 to avoid start clock() - // of 0 as being a timeout - timelimit = clock() + 1; - } - else if (timelimit != 0 && (clock() > timelimit + TIMELIMIT)) { - timelimit = 0; + // set the start time + clock_time_start = clock_now; + timelimit_exceeded = false; } + else if (std::chrono::duration_cast(clock_now - clock_time_start).count() + > TIMELIMIT * CLOCKS_PER_SEC * 1000) + timelimit_exceeded = true; setcminmax(&cmin, &cmax, word.c_str(), len); @@ -1626,7 +1630,7 @@ struct hentry* AffixMgr::compound_check(const std::string& word, do { // simplified checkcompoundpattern loop - if (timelimit == 0) + if (timelimit_exceeded) return 0; if (scpd > 0) { @@ -2216,17 +2220,20 @@ int AffixMgr::compound_check_morph(const std::string& word, // add a time limit to handle possible // combinatorical explosion of the overlapping words - HUNSPELL_THREAD_LOCAL clock_t timelimit; + HUNSPELL_THREAD_LOCAL std::chrono::steady_clock::time_point clock_time_start; + HUNSPELL_THREAD_LOCAL bool timelimit_exceeded; + + // get the current time + std::chrono::steady_clock::time_point clock_now = std::chrono::steady_clock::now(); if (wordnum == 0) { - // get the start time, seeing as we're reusing this set to 0 - // to flag timeout, use clock() + 1 to avoid start clock() - // of 0 as being a timeout - timelimit = clock() + 1; - } - else if (timelimit != 0 && (clock() > timelimit + TIMELIMIT)) { - timelimit = 0; + // set the start time + clock_time_start = clock_now; + timelimit_exceeded = false; } + else if (std::chrono::duration_cast(clock_now - clock_time_start).count() + > TIMELIMIT * CLOCKS_PER_SEC * 1000) + timelimit_exceeded = true; setcminmax(&cmin, &cmax, word.c_str(), len); @@ -2246,7 +2253,7 @@ int AffixMgr::compound_check_morph(const std::string& word, do { // onlycpdrule loop - if (timelimit == 0) + if (timelimit_exceeded) return 0; oldnumsyllable = numsyllable; -- 2.41.0