Skip to content

Slow lookup #323

@Roman-Koshelev

Description

@Roman-Koshelev

Compared lookup + ToTm with analogs from C/C++. It turned out to be 2.5 and 8 times slower. cctz takes the last date of the time zone and shifts it. Also, for optimization, we add some transitions (constantly moving them too). Strange and slow. Do you want to fix it?

Bencmark

BM_Time_ToCivilUTC_CCTZ                55.4 ns         55.4 ns     12012245      8.38x
BM_Time_ToCivilUTC_Libc                22.6 ns         22.6 ns     30427869      3.42x
BM_Time_ToCivilUTC_Libcpp              6.61 ns         6.87 ns     97881024      1x

Source code BM_Time_ToCivilUTC_Libcpp

constexpr int get_yearday(const std::chrono::year_month_day& ymd) noexcept {
    constexpr int k_month_offsets[1 + 12] = {
      -1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
  };
  const int feb29 = (ymd.month() > std::chrono::February && ymd.year().is_leap());
  const unsigned month = static_cast<unsigned>(ymd.month());
  return k_month_offsets[month] + feb29 + static_cast<unsigned>(ymd.day()) - 1;
}

std::tm TpToTm(const std::chrono::system_clock::time_point tp) {
    std::chrono::sys_days days = std::chrono::floor<std::chrono::days>(tp);
    std::chrono::year_month_day ymd{days};
    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(tp - days);
    std::chrono::hh_mm_ss<std::chrono::seconds> hms{seconds};

    std::tm tm{};
    tm.tm_year = static_cast<int>(ymd.year()) - 1900;
    tm.tm_mon = static_cast<unsigned>(ymd.month()) - 1;
    tm.tm_mday = static_cast<unsigned>(ymd.day());
    tm.tm_wday = static_cast<unsigned>(std::chrono::weekday{days}.c_encoding());
    tm.tm_yday = get_yearday(ymd);
    tm.tm_hour = hms.hours().count(); 
    tm.tm_min = hms.minutes().count();
    tm.tm_sec = hms.seconds().count();

    return tm;
}

void BM_Time_ToCivilUTC_Libcpp(benchmark::State& state) {
  std::chrono::system_clock::time_point tp =
      std::chrono::system_clock::from_time_t(1384569027);
  while (state.KeepRunning()) {
    tp += std::chrono::seconds(1);
    
    benchmark::DoNotOptimize(TpToTm(tp)); 
  }
}
BENCHMARK(BM_Time_ToCivilUTC_Libcpp);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions