Commit bfb60af5 authored by captainwong's avatar captainwong

time

parent b2860dd6
......@@ -10,4 +10,8 @@
#ifdef JLIB_WINDOWS
#define _CRT_SECURE_NO_WARNINGS
// https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
#define ENABLE_EBO __declspec(empty_bases)
#else
#define ENABLE_EBO
#endif
#pragma once
// for cross-platform
#include "config.h"
#include <time.h>
#include <stdint.h>
#ifdef JLIB_WINDOWS
# include <windows.h>
static inline struct tm* gmtime_r(const time_t* timep, struct tm* result)
{
gmtime_s(result, timep);
return result;
}
#else
# include <sys/time.h> // gettimeofday
#endif
namespace jlib {
static constexpr int MICRO_SECONDS_PER_SECOND = 1000 * 1000;
/* FILETIME of Jan 1 1970 00:00:00. */
static constexpr uint64_t EPOCH = 116444736000000000UL;
static inline int64_t gettimeofdayUsec()
{
#ifdef JLIB_WINDOWS
FILETIME ft = { 0 };
#if _WIN32_WINNT > _WIN32_WINNT_WIN7
GetSystemTimePreciseAsFileTime(&ft); // win8 or later
#else // before win8
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
#endif // _WIN32_WINNT > _WIN32_WINNT_WIN7
ULARGE_INTEGER ularge;
ularge.LowPart = ft.dwLowDateTime;
ularge.HighPart = ft.dwHighDateTime;
return (ularge.QuadPart - EPOCH) / 10L;
#elif defined(JLIB_LINUX)
struct timeval tv;
gettimeofday(&tv, nullptr);
int64_t seconds = tv.tv_sec;
return seconds * MICRO_SECONDS_PER_SECOND + tv.tv_usec;
#endif // JLIB_WINDOWS
return 0;
}
}
......@@ -7,25 +7,10 @@
#include <string> // std::string
#include <inttypes.h> // PRId64
#include <stdio.h> // snprintf
#include <time.h> // gmtime_r
#include "time.h"
//#define _WIN32_WINNT _WIN32_WINNT_WIN7
#ifdef JLIB_WINDOWS
# include <windows.h>
static inline struct tm* gmtime_r(const time_t* timep, struct tm* result)
{
gmtime_s(result, timep);
return result;
}
// https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
# define ENABLE_EBO __declspec(empty_bases)
#elif defined(JLIB_LINUX)
# include <sys/time.h> // gettimeofday
# define ENABLE_EBO
#endif
namespace jlib
{
......@@ -43,7 +28,6 @@ public:
: microSecondsSinceEpoch_(microSecondsSinceEpoch)
{}
static constexpr int MICRO_SECONDS_PER_SECOND = 1000 * 1000;
void swap(Timestamp& rhs) {
std::swap(microSecondsSinceEpoch_, rhs.microSecondsSinceEpoch_);
......@@ -84,31 +68,7 @@ public:
static Timestamp now() {
#ifdef JLIB_WINDOWS
/* FILETIME of Jan 1 1970 00:00:00. */
static constexpr unsigned __int64 EPOCH = 116444736000000000UL;
FILETIME ft;
#if _WIN32_WINNT > _WIN32_WINNT_WIN7
GetSystemTimePreciseAsFileTime(&ft); // win8 or later
#else
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
#endif
ULARGE_INTEGER ularge;
ularge.LowPart = ft.dwLowDateTime;
ularge.HighPart = ft.dwHighDateTime;
return Timestamp((ularge.QuadPart - EPOCH) / 10L);
#elif defined(JLIB_LINUX)
struct timeval tv;
gettimeofday(&tv, nullptr);
int64_t seconds = tv.tv_sec;
return Timestamp(seconds * MICRO_SECONDS_PER_SECOND + tv.tv_usec);
#endif
return Timestamp(gettimeofdayUsec());
}
static Timestamp invalid() { return Timestamp(); }
......@@ -121,7 +81,6 @@ public:
return Timestamp(static_cast<int64_t>(t) * MICRO_SECONDS_PER_SECOND + microSeconds);
}
private:
int64_t microSecondsSinceEpoch_ = 0;
};
......@@ -143,11 +102,11 @@ inline bool operator==(Timestamp lhs, Timestamp rhs) {
*/
inline double timeDifference(Timestamp high, Timestamp low) {
int64_t diff = high.microSecondsSinceEpoch() - low.microSecondsSinceEpoch();
return static_cast<double>(diff) / Timestamp::MICRO_SECONDS_PER_SECOND;
return static_cast<double>(diff) / MICRO_SECONDS_PER_SECOND;
}
inline Timestamp addSeconds(Timestamp t, double seconds) {
int64_t delta = static_cast<int64_t>(seconds * Timestamp::MICRO_SECONDS_PER_SECOND);
int64_t delta = static_cast<int64_t>(seconds * MICRO_SECONDS_PER_SECOND);
return Timestamp(t.microSecondsSinceEpoch() + delta);
}
......
......@@ -70,12 +70,18 @@ struct LocalTime
static constexpr int SECONDS_PER_DAY = 24 * 60 * 60;
//! TimeZone for 1970~2030
class Timezone : public copyable
{
public:
explicit Timezone(const char* zonename);
Timezone(int bias, const char* tzname);
explicit Timezone(const char* zonename) {
}
Timezone(int bias, const char* tzname) {
}
Timezone() = default; // invalid timezone
bool valid() const{
......
......@@ -27,7 +27,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "jlib", "jlib", "{42703978-A
..\jlib\win32.h = ..\jlib\win32.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "thirdparty", "thirdparty", "{5A2CA1BE-5A4B-41B0-B74A-F86AB433F4A5}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rdparty", "3rdparty", "{5A2CA1BE-5A4B-41B0-B74A-F86AB433F4A5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "base", "base", "{608A105E-40DB-44FD-8FC2-A66AB921688D}"
ProjectSection(SolutionItems) = preProject
......@@ -40,6 +40,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "base", "base", "{608A105E-4
..\jlib\base\noncopyable.h = ..\jlib\base\noncopyable.h
..\jlib\base\singleton.h = ..\jlib\base\singleton.h
..\jlib\base\stringpiece.h = ..\jlib\base\stringpiece.h
..\jlib\base\time.h = ..\jlib\base\time.h
..\jlib\base\timestamp.h = ..\jlib\base\timestamp.h
..\jlib\base\timezone.h = ..\jlib\base\timezone.h
EndProjectSection
......@@ -186,6 +187,40 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "curl", "curl", "{F441BB78-6
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_curl_wrapper", "test_curl_wrapper\test_curl_wrapper.vcxproj", "{175611D7-9C38-4269-B0B4-66DE9555A8EB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "base_tests", "base_tests", "{D9BC4E5B-7E8F-4C86-BF15-CCB75CBC256F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "qt", "qt", "{F118E1C9-F461-4CAA-A0F1-75F5A5C8ADF3}"
ProjectSection(SolutionItems) = preProject
..\jlib\qt\ErrorCode.h = ..\jlib\qt\ErrorCode.h
..\jlib\qt\QtDebug.h = ..\jlib\qt\QtDebug.h
..\jlib\qt\QtDebugOutput.h = ..\jlib\qt\QtDebugOutput.h
..\jlib\qt\QtPathHelper.h = ..\jlib\qt\QtPathHelper.h
..\jlib\qt\QtStylesheet.h = ..\jlib\qt\QtStylesheet.h
..\jlib\qt\QtUtils.h = ..\jlib\qt\QtUtils.h
..\jlib\qt\signal_slot.h = ..\jlib\qt\signal_slot.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ctrl", "Ctrl", "{0E82BB61-0D27-42B4-8F11-98DB2A21C168}"
ProjectSection(SolutionItems) = preProject
..\jlib\qt\Ctrl\ThreadCtrl.h = ..\jlib\qt\Ctrl\ThreadCtrl.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Model", "Model", "{42039C84-62EE-4F71-A4B9-E9DB2880357C}"
ProjectSection(SolutionItems) = preProject
..\jlib\qt\Model\ThreadModel.h = ..\jlib\qt\Model\ThreadModel.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "View", "View", "{16CAD8DD-EF99-4A38-B5AA-BF86FC7A07AB}"
ProjectSection(SolutionItems) = preProject
..\jlib\qt\View\BgColorBtn.h = ..\jlib\qt\View\BgColorBtn.h
..\jlib\qt\View\HttpDlg.h = ..\jlib\qt\View\HttpDlg.h
..\jlib\qt\View\HttpDlgErrorCode.h = ..\jlib\qt\View\HttpDlgErrorCode.h
..\jlib\qt\View\IconBtn.h = ..\jlib\qt\View\IconBtn.h
..\jlib\qt\View\LoadingView.h = ..\jlib\qt\View\LoadingView.h
..\jlib\qt\View\PageTitle.h = ..\jlib\qt\View\PageTitle.h
..\jlib\qt\View\RndButton.h = ..\jlib\qt\View\RndButton.h
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
......@@ -299,12 +334,12 @@ Global
{A4B1CDB2-7325-4E22-AD0A-1D2907924CDB} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
{B12702AD-ABFB-343A-A199-8E24837244A3} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{8A39D7AF-50AF-43BD-8CC6-DA20B6349F03} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{372670F2-83A5-4058-B93C-BB0DCC1521ED} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{372670F2-83A5-4058-B93C-BB0DCC1521ED} = {D9BC4E5B-7E8F-4C86-BF15-CCB75CBC256F}
{5A2CA1BE-5A4B-41B0-B74A-F86AB433F4A5} = {42703978-A988-403D-9723-E35527FA8A07}
{608A105E-40DB-44FD-8FC2-A66AB921688D} = {42703978-A988-403D-9723-E35527FA8A07}
{B4B8F20B-1B3E-42CD-8B37-A734EF3CA279} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{3E322E9F-E560-4300-AFF8-1DCE44E7DDA2} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{8A9333D5-2981-4E92-87BF-AFFC5F99B1A4} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{B4B8F20B-1B3E-42CD-8B37-A734EF3CA279} = {D9BC4E5B-7E8F-4C86-BF15-CCB75CBC256F}
{3E322E9F-E560-4300-AFF8-1DCE44E7DDA2} = {D9BC4E5B-7E8F-4C86-BF15-CCB75CBC256F}
{8A9333D5-2981-4E92-87BF-AFFC5F99B1A4} = {D9BC4E5B-7E8F-4C86-BF15-CCB75CBC256F}
{B5D9E71E-2BFE-4D04-A66A-4CB0A103CD77} = {42703978-A988-403D-9723-E35527FA8A07}
{9A3F45EB-C57C-4789-8177-0DEFCC5AFD0E} = {B5D9E71E-2BFE-4D04-A66A-4CB0A103CD77}
{0E6598D3-602D-4552-97F7-DC5AB458D553} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
......@@ -320,6 +355,11 @@ Global
{41E61D5E-42D7-4EEA-A6B5-3D13DB455848} = {5A2CA1BE-5A4B-41B0-B74A-F86AB433F4A5}
{F441BB78-6FE1-4FCB-80C3-9FC5F8131996} = {5A2CA1BE-5A4B-41B0-B74A-F86AB433F4A5}
{175611D7-9C38-4269-B0B4-66DE9555A8EB} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{D9BC4E5B-7E8F-4C86-BF15-CCB75CBC256F} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{F118E1C9-F461-4CAA-A0F1-75F5A5C8ADF3} = {42703978-A988-403D-9723-E35527FA8A07}
{0E82BB61-0D27-42B4-8F11-98DB2A21C168} = {F118E1C9-F461-4CAA-A0F1-75F5A5C8ADF3}
{42039C84-62EE-4F71-A4B9-E9DB2880357C} = {F118E1C9-F461-4CAA-A0F1-75F5A5C8ADF3}
{16CAD8DD-EF99-4A38-B5AA-BF86FC7A07AB} = {F118E1C9-F461-4CAA-A0F1-75F5A5C8ADF3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A8EBEA58-739C-4DED-99C0-239779F57D5D}
......
......@@ -3,7 +3,7 @@
#include "pch.h"
#include <iostream>
#include "../../jlib/json/json.h"
#include "../../jlib/3rdparty/json/json.h"
int main()
{
......
#include <jlib/base/timestamp.h>
#include "../../jlib/base/timestamp.h"
#include <vector>
#include <stdio.h>
#include <chrono>
......@@ -7,142 +7,54 @@ using jlib::Timestamp;
void passByConstReference(const Timestamp& x)
{
printf("%s\n", x.toString().c_str());
printf("passByConstReference: %s\n", x.toString().c_str());
}
void passByValue(Timestamp x)
{
printf("%s\n", x.toString().c_str());
printf("passByValue: %s\n", x.toString().c_str());
}
void benchmark()
{
printf("benchmark\n");
const int kNumber = 1000 * 1000;
std::vector<Timestamp> stamps;
stamps.reserve(kNumber);
for (int i = 0; i < kNumber; ++i)
{
for (int i = 0; i < kNumber; ++i) {
stamps.push_back(Timestamp::now());
}
printf("%s\n", stamps.front().toString().c_str());
printf("%s\n", stamps.back().toString().c_str());
printf("%f\n", timeDifference(stamps.back(), stamps.front()));
printf("front %s\n", stamps.front().toString().c_str());
printf("back %s\n", stamps.back().toString().c_str());
printf("timeDifference %f\n", timeDifference(stamps.back(), stamps.front()));
int increments[100] = { 0 };
int64_t start = stamps.front().microSecondsSinceEpoch();
for (int i = 1; i < kNumber; ++i)
{
for (int i = 1; i < kNumber; ++i) {
int64_t next = stamps[i].microSecondsSinceEpoch();
int64_t inc = next - start;
start = next;
if (inc < 0)
{
if (inc < 0) {
printf("reverse!\n");
} else if (inc < 100)
{
} else if (inc < 100) {
++increments[inc];
} else
{
} else {
printf("big gap %d\n", static_cast<int>(inc));
}
}
for (int i = 0; i < 100; ++i)
{
for (int i = 0; i < 100; ++i) {
printf("%2d: %d\n", i, increments[i]);
}
}
struct __declspec(empty_bases) foo : public jlib::copyable
, public boost::equality_comparable<foo>
{
public:
void bar() {
}
static constexpr int64_t n = 0;
private:
int64_t m;
};
void test_time()
{
{
time_t t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
}
{
time_t t = 0;
struct tm tm;
gmtime_r(&t, &tm);
time_t now = time(nullptr);
gmtime_r(&now, &tm);
tm.tm_isdst = -1;
t = mktime(&tm);
tm.tm_year += 1900;
tm.tm_mon++;
SYSTEMTIME st;
GetSystemTime(&st);
}
// get epoch
{
SYSTEMTIME st;
GetSystemTime(&st);
st.wYear = 1970;
st.wMonth = 1;
st.wDay = 1;
st.wHour = 0;
st.wMinute = 0;
st.wSecond = 0;
st.wMilliseconds = 0;
struct tm tm = { 0 };
tm.tm_year = 70;
tm.tm_mon = 0;
tm.tm_mday = 1;
tm.tm_mday = 4;
tm.tm_isdst = -1;
time_t t = mktime(&tm);
gmtime_r(&t, &tm);
tm.tm_year += 1900;
}
LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency);
LARGE_INTEGER large;
QueryPerformanceCounter(&large);
Timestamp t(((large.QuadPart ) * 1000000 / Frequency.QuadPart));
printf("%s\n", t.toFormattedString().c_str());
/*FILETIME ft;
GetSystemTimePreciseAsFileTime(&ft);
ULARGE_INTEGER ularge;
ularge.LowPart = ft.dwLowDateTime;
ularge.HighPart = ft.dwHighDateTime;
*/
}
int main()
{
test_time();
printf("sizeof foo=%zd, sizeof int64_t=%zd\n", sizeof(foo), sizeof(int64_t));
printf("sizeof Timestamp=%zd, sizeof int64_t=%zd\n", sizeof(Timestamp), sizeof(int64_t));
Timestamp now(Timestamp::now());
printf("%s\n", now.toString().c_str());
printf("%s\n", now.toFormattedString().c_str());
printf("now.toString(): %s\n", now.toString().c_str());
printf("now.toFormattedString(): %s\n", now.toFormattedString().c_str());
passByValue(now);
passByConstReference(now);
benchmark();
......
......@@ -88,6 +88,7 @@
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(BOOST);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
......@@ -125,7 +126,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="test_timestamp.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
......
......@@ -15,7 +15,7 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<ClCompile Include="test_timestamp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment