in be/src/benchmarks/convert-timestamp-benchmark.cc [710:1024]
int main(int argc, char* argv[]) {
impala::InitCommonRuntime(argc, argv, true, impala::TestInfo::BE_TEST);
impala::InitFeSupport();
TestEnv test_env;
CHECK(test_env.Init().ok());
cout << Benchmark::GetMachineInfo() << endl;
ABORT_IF_ERROR(TimezoneDatabase::Initialize());
const string& local_tz_name = TimezoneDatabase::LocalZoneName();
DCHECK(local_tz_name != "");
PTR_CCTZ_LOCAL_TZ = TimezoneDatabase::FindTimezone(local_tz_name);
DCHECK(PTR_CCTZ_LOCAL_TZ != nullptr);
SimpleDateFormatTokenizer::InitCtx();
const vector<TimestampValue> tsvalue_data =
AddTestDataDateTimes(1000, "1953-04-22 01:02:03");
// Benchmark UtcToUnixTime conversion with glibc/cctz/boost
Benchmark bm_utc_to_unix("UtcToUnixTime");
TestData<TimestampValue, time_t, glibc_utc_to_unix_time> glibc_utc_to_unix_data =
tsvalue_data;
TestData<TimestampValue, time_t, cctz_utc_to_unix_time> cctz_utc_to_unix_data =
tsvalue_data;
TestData<TimestampValue, time_t, boost_utc_to_unix_time> boost_utc_to_unix_data =
tsvalue_data;
glibc_utc_to_unix_data.add_to_benchmark(bm_utc_to_unix, "(glibc)");
cctz_utc_to_unix_data.add_to_benchmark(bm_utc_to_unix, "(Google/CCTZ)");
boost_utc_to_unix_data.add_to_benchmark(bm_utc_to_unix, "(boost)");
cout << bm_utc_to_unix.Measure() << endl;
bail_if_results_dont_match(vector<const vector<time_t>*>{
&cctz_utc_to_unix_data.result(), &glibc_utc_to_unix_data.result(),
&boost_utc_to_unix_data.result()});
// Benchmark LocalToUnixTime conversion with glibc/cctz
Benchmark bm_local_to_unix("LocalToUnixTime");
TestData<TimestampValue, time_t, glibc_local_to_unix_time> glibc_local_to_unix_data =
tsvalue_data;
TestData<TimestampValue, time_t, cctz_local_to_unix_time> cctz_local_to_unix_data =
tsvalue_data;
glibc_local_to_unix_data.add_to_benchmark(bm_local_to_unix, "(glibc)");
cctz_local_to_unix_data.add_to_benchmark(bm_local_to_unix, "(Google/CCTZ)");
cout << bm_local_to_unix.Measure() << endl;
bail_if_results_dont_match(vector<const vector<time_t>*>{
&glibc_local_to_unix_data.result(), &cctz_local_to_unix_data.result()});
// Benchmark FromUtc with boost/cctz
vector<TimestampVal> tsval_data;
for (const TimestampValue& tsvalue: tsvalue_data) {
TimestampVal tsval;
tsvalue.ToTimestampVal(&tsval);
tsval_data.push_back(tsval);
}
Benchmark bm_from_utc("FromUtc");
TestData<TimestampVal, TimestampVal, boost_from_utc> boost_from_utc_data = tsval_data;
TestData<TimestampVal, TimestampVal, cctz_from_utc> cctz_from_utc_data = tsval_data;
boost_from_utc_data.add_to_benchmark(bm_from_utc, "(boost)");
cctz_from_utc_data.add_to_benchmark(bm_from_utc, "(Google/CCTZ)");
cout << bm_from_utc.Measure() << endl;
// We don't expect boost/cctz FromUtc results to match (they use non-compatible
// time-zone databases for conversion).
// Benchmark ToUtc with boost/cctz
Benchmark bm_to_utc("ToUtc");
TestData<TimestampVal, TimestampVal, boost_to_utc> boost_to_utc_data = tsval_data;
TestData<TimestampVal, TimestampVal, cctz_to_utc> cctz_to_utc_data = tsval_data;
boost_to_utc_data.add_to_benchmark(bm_to_utc, "(boost)");
cctz_to_utc_data.add_to_benchmark(bm_to_utc, "(Google/CCTZ)");
cout << bm_to_utc.Measure() << endl;
// We don't expect boost/cctz ToUtc results to match (they use non-compatible time-zone
// databases for conversion).
// Benchmark UtcToLocal with glibc/cctz
Benchmark bm_utc_to_local("UtcToLocal");
TestData<TimestampValue, TimestampValue, glibc_utc_to_local> glibc_utc_to_local_data =
tsvalue_data;
TestData<TimestampValue, TimestampValue, cctz_utc_to_local> cctz_utc_to_local_data =
tsvalue_data;
TestData<TimestampValue, TimestampValue, jvm_utc_to_local> jvm_utc_to_local_data =
tsvalue_data;
glibc_utc_to_local_data.add_to_benchmark(bm_utc_to_local, "(glibc)");
cctz_utc_to_local_data.add_to_benchmark(bm_utc_to_local, "(Google/CCTZ)");
jvm_utc_to_local_data.add_to_benchmark(bm_utc_to_local, "(JVM)");
cout << bm_utc_to_local.Measure() << endl;
bail_if_results_dont_match(vector<const vector<TimestampValue>*>{
&glibc_utc_to_local_data.result(), &cctz_utc_to_local_data.result()});
// Benchmark UnixTimeToLocalPtime with glibc/cctz
vector<time_t> time_data;
for (const TimestampValue& tsvalue: tsvalue_data) {
time_t unix_time;
tsvalue.ToUnixTime(UTCPTR, &unix_time);
time_data.push_back(unix_time);
}
Benchmark bm_unix_time_to_local_ptime("UnixTimeToLocalPtime");
TestData<
time_t,
boost::posix_time::ptime,
glibc_unix_time_to_local_ptime> glibc_unix_time_to_local_ptime_data = time_data;
TestData<
time_t,
boost::posix_time::ptime,
cctz_unix_time_to_local_ptime> cctz_unix_time_to_local_ptime_data = time_data;
glibc_unix_time_to_local_ptime_data.add_to_benchmark(bm_unix_time_to_local_ptime,
"(glibc)");
cctz_unix_time_to_local_ptime_data.add_to_benchmark(bm_unix_time_to_local_ptime,
"(Google/CCTZ)");
cout << bm_unix_time_to_local_ptime.Measure() << endl;
bail_if_results_dont_match(vector<const vector<boost::posix_time::ptime>*>{
&glibc_unix_time_to_local_ptime_data.result(),
&cctz_unix_time_to_local_ptime_data.result()});
// Benchmark UnixTimeToUtcPtime with glibc/cctz/fastpath
Benchmark bm_unix_time_to_utc_ptime("UnixTimeToUtcPtime");
TestData<
time_t,
boost::posix_time::ptime,
glibc_unix_time_to_utc_ptime> glibc_unix_time_to_utc_ptime_data = time_data;
TestData<
time_t,
boost::posix_time::ptime,
cctz_unix_time_to_utc_ptime> cctz_unix_time_to_utc_ptime_data = time_data;
TestData<
time_t,
boost::posix_time::ptime,
fastpath_unix_time_to_utc_ptime> fastpath_unix_time_to_utc_ptime_data = time_data;
TestData<
time_t,
boost::posix_time::ptime,
split_unix_time_to_utc_ptime> split_unix_time_to_utc_ptime_data = time_data;
glibc_unix_time_to_utc_ptime_data.add_to_benchmark(bm_unix_time_to_utc_ptime,
"(glibc)");
cctz_unix_time_to_utc_ptime_data.add_to_benchmark(bm_unix_time_to_utc_ptime,
"(Google/CCTZ)");
fastpath_unix_time_to_utc_ptime_data.add_to_benchmark(bm_unix_time_to_utc_ptime,
"(fast path)");
split_unix_time_to_utc_ptime_data.add_to_benchmark(bm_unix_time_to_utc_ptime,
"(day split)");
cout << bm_unix_time_to_utc_ptime.Measure() << endl;
bail_if_results_dont_match(vector<const vector<boost::posix_time::ptime>*>{
&glibc_unix_time_to_utc_ptime_data.result(),
&cctz_unix_time_to_utc_ptime_data.result(),
&fastpath_unix_time_to_utc_ptime_data.result(),
&split_unix_time_to_utc_ptime_data.result()});
// Benchmark UtcFromUnixTimeMicros improvement in IMPALA-7417.
vector<time_t> microsec_data;
for (int i = 0; i < tsvalue_data.size(); ++i) {
const TimestampValue& tsvalue = tsvalue_data[i];
time_t unix_time;
tsvalue.ToUnixTime(UTCPTR, &unix_time);
int micros = (i * 1001) % MICROS_PER_SEC; // add some sub-second part
microsec_data.push_back(unix_time * MICROS_PER_SEC + micros);
}
Benchmark bm_utc_from_unix_time_micros("UtcFromUnixTimeMicros");
TestData<int64_t, TimestampValue, sec_split_utc_from_unix_time_micros>
sec_split_utc_from_unix_time_micros_data = microsec_data;
TestData<int64_t, TimestampValue, day_split_utc_from_unix_time_micros>
day_split_utc_from_unix_time_micros_data = microsec_data;
sec_split_utc_from_unix_time_micros_data.add_to_benchmark(bm_utc_from_unix_time_micros,
"(sec split (old))");
day_split_utc_from_unix_time_micros_data.add_to_benchmark(bm_utc_from_unix_time_micros,
"(day split)");
cout << bm_utc_from_unix_time_micros.Measure() << endl;
bail_if_results_dont_match(vector<const vector<TimestampValue>*>{
&sec_split_utc_from_unix_time_micros_data.result(),
&day_split_utc_from_unix_time_micros_data.result()});
// Benchmark FromUnixTimeNanos improvement in IMPALA-7417.
vector<SplitNanoAndSecond> nanosec_data;
for (int i = 0; i < tsvalue_data.size(); ++i) {
const TimestampValue& tsvalue = tsvalue_data[i];
time_t unix_time;
tsvalue.ToUnixTime(UTCPTR, &unix_time);
int nanos = (i * 1001) % NANOS_PER_SEC; // add some sub-second part
nanosec_data.push_back(SplitNanoAndSecond {unix_time, nanos} );
}
Benchmark bm_utc_from_unix_time_nanos("FromUnixTimeNanos");
TestData<SplitNanoAndSecond, TimestampValue, old_split_utc_from_unix_time_nanos>
old_split_utc_from_unix_time_nanos_data = nanosec_data;
TestData<SplitNanoAndSecond, TimestampValue, new_split_utc_from_unix_time_nanos>
new_split_utc_from_unix_time_nanos_data = nanosec_data;
old_split_utc_from_unix_time_nanos_data.add_to_benchmark(bm_utc_from_unix_time_nanos,
"(sec split (old))");
new_split_utc_from_unix_time_nanos_data.add_to_benchmark(bm_utc_from_unix_time_nanos,
"(sec split (new))");
cout << bm_utc_from_unix_time_nanos.Measure() << endl;
bail_if_results_dont_match(vector<const vector<TimestampValue>*>{
&old_split_utc_from_unix_time_nanos_data.result(),
&new_split_utc_from_unix_time_nanos_data.result()});
// Benchmark FromSubsecondUnixTime before and after IMPALA-7417.
vector<double> double_data;
for (int i = 0; i < tsvalue_data.size(); ++i) {
const TimestampValue& tsvalue = tsvalue_data[i];
time_t unix_time;
tsvalue.ToUnixTime(UTCPTR, &unix_time);
double nanos = (i * 1001) % NANOS_PER_SEC; // add some sub-second part
double_data.push_back((double)unix_time + nanos / NANOS_PER_SEC);
}
Benchmark from_subsecond_unix_time("FromSubsecondUnixTime");
TestData<double, TimestampValue, from_subsecond_unix_time_old>
from_subsecond_unix_time_old_data = double_data;
TestData<double, TimestampValue, from_subsecond_unix_time_new>
from_subsecond_unix_time_new_data = double_data;
from_subsecond_unix_time_old_data.add_to_benchmark(from_subsecond_unix_time, "(old)");
from_subsecond_unix_time_new_data.add_to_benchmark(from_subsecond_unix_time, "(new)");
cout << from_subsecond_unix_time.Measure() << endl;
bail_if_results_dont_match(vector<const vector<TimestampValue>*>{
&from_subsecond_unix_time_old_data.result(),
&from_subsecond_unix_time_new_data.result()});
// If number of threads is specified, run multithreaded tests.
int num_of_threads = (argc < 2) ? 0 : atoi(argv[1]);
if (num_of_threads >= 1) {
const int BATCH_SIZE = 1000;
cout << "Number of threads: " << num_of_threads << endl;
uint64_t m1 = 0, m2 = 0, m3 = 0;
// UtcToUnixTime
cout << endl << "UtcToUnixTime:" << endl;
m1 = glibc_utc_to_unix_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsvalue_data, "(glibc)");
m2 = cctz_utc_to_unix_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsvalue_data, "(Google/CCTZ)");
m3 = boost_utc_to_unix_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsvalue_data, "(boost)");
cout << "cctz speedup: " << double(m1)/double(m2) << endl;
cout << "boost speedup: " << double(m1)/double(m3) << endl;
// LocalToUnixTime
cout << endl << "LocalToUnixTime:" << endl;
m1 = glibc_local_to_unix_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsvalue_data, "(glibc)");
m2 = cctz_local_to_unix_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsvalue_data, "(Google/CCTZ)");
cout << "speedup: " << double(m1)/double(m2) << endl;
// FromUtc
cout << endl << "FromUtc:" << endl;
m1 = boost_from_utc_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsval_data, "(boost)");
m2 = cctz_from_utc_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsval_data, "(Google/CCTZ)");
cout << "speedup: " << double(m1)/double(m2) << endl;
// ToUtc
cout << endl << "ToUtc:" << endl;
m1 = boost_to_utc_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsval_data, "(boost)");
m2 = cctz_to_utc_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsval_data, "(Google/CCTZ)");
cout << "speedup: " << double(m1)/double(m2) << endl;
// UtcToLocal
cout << endl << "UtcToLocal:" << endl;
m1 = glibc_utc_to_local_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsvalue_data, "(glibc)");
m2 = cctz_utc_to_local_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsvalue_data, "(Google/CCTZ)");
m3 = jvm_utc_to_local_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, tsvalue_data, "(JVM)");
cout << "cctz speedup: " << double(m1)/double(m2) << endl;
cout << "jvm speedup: " << double(m1)/double(m3) << endl;
// UnixTimeToLocalPtime
cout << endl << "UnixTimeToLocalPtime:" << endl;
m1 = glibc_unix_time_to_local_ptime_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, time_data, "(glibc)");
m2 = cctz_unix_time_to_local_ptime_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, time_data, "(Google/CCTZ)");
cout << "speedup: " << double(m1)/double(m2) << endl;
// UnixTimeToUtcPtime
cout << endl << "UnixTimeToUtcPtime:" << endl;
m1 = glibc_unix_time_to_utc_ptime_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, time_data, "(glibc)");
m2 = cctz_unix_time_to_utc_ptime_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, time_data, "(Google/CCTZ)");
m3 = fastpath_unix_time_to_utc_ptime_data.measure_multithreaded_elapsed_time(
num_of_threads, BATCH_SIZE, time_data, "(fast path)");
cout << "cctz speedup: " << double(m1)/double(m2) << endl;
cout << "fast path speedup: " << double(m1)/double(m3) << endl;
}
return 0;
}