diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 378569b..efecd2b 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -41,14 +41,26 @@ "state": { "type": "markdown", "state": { - "file": "04. Programming/QT/timer.md", + "file": "03. 專注Study/C++/C++20.md", + "mode": "source", + "source": true + } + } + }, + { + "id": "bedfb1c3a1e0e733", + "type": "leaf", + "state": { + "type": "markdown", + "state": { + "file": "03. 專注Study/C++/chrono.md", "mode": "source", "source": true } } } ], - "currentTab": 2 + "currentTab": 3 } ], "direction": "vertical" @@ -106,7 +118,7 @@ "state": { "type": "backlink", "state": { - "file": "04. Programming/QT/timer.md", + "file": "03. 專注Study/C++/chrono.md", "collapseAll": false, "extraContext": false, "sortOrder": "alphabetical", @@ -131,7 +143,7 @@ "state": { "type": "outline", "state": { - "file": "04. Programming/QT/timer.md" + "file": "03. 專注Study/C++/chrono.md" } } }, @@ -144,7 +156,7 @@ } } ], - "currentTab": 3 + "currentTab": 1 }, { "id": "ae4bf98badbfc7ee", @@ -182,10 +194,13 @@ "periodic-notes:Open today": false } }, - "active": "90e723ca7b21bf9e", + "active": "bedfb1c3a1e0e733", "lastOpenFiles": [ - "00. Inbox/01. TODO.md", + "03. 專注Study/C++/C++20.md", + "03. 專注Study/C++/chrono.md", + "03. 專注Study/C++/C++17.md", "04. Programming/QT/timer.md", + "00. Inbox/01. TODO.md", "00. Inbox/想要的鏡頭.md", "05. 資料收集/Capture One.md", "04. Programming/OpenCV API.md", @@ -211,9 +226,6 @@ "02. 工作/01. Logitech/Bolide.md", "02. 工作/01. Logitech/AutoStation.md", "02. 工作/01. Logitech/AE Team.md", - "02. 工作/01. Logitech/00. OurTeam.md", - "05. 資料收集/軟體工具/git/tag.md", - "04. Programming/Kotlin/AtomicBoolean.md", "attachments/android_mediacodec_life_cycle.png", "attachments/android_mediacodec_flow.png", "attachments/Pasted image 20230308105856.png", diff --git a/03. 專注Study/C++/chrono.md b/03. 專注Study/C++/chrono.md new file mode 100644 index 0000000..4165a14 --- /dev/null +++ b/03. 專注Study/C++/chrono.md @@ -0,0 +1,79 @@ +Language: C++11 + +## header +```cpp +#include  +``` + +## duration +duration 是 chrono 裡面,用來記錄時間長度的類別,他基本上是一個 template class,可以自行定義他的意義;chrono 也有提供一些比較常見的時間類別,可以直接拿來使用,下面就是內建的 duration 的型別: +```cpp +typedef duration nanoseconds; +typedef duration microseconds; +typedef duration milliseconds; +typedef duration seconds; +typedef duration > minutes; +typedef duration > hours; +``` + +其中可以看到,第一個 template 參數是要用來儲存資料的型別,第二個則是他相對於「秒」的比例。這邊也使用了 ratio 這個 C++11 的另一個新的函式庫的類別,他是用來記錄「有理數」(可以寫成分數的數)的新類別,有興趣可以參考 [cppreference 的介紹](http://en.cppreference.com/w/cpp/numeric/ratio/ratio)。 + +基本上,一般會用到時間單位這邊都有定義好了,如果不合用的話,也可以自己去定義;而由於 chrono 也有把相關的計算都定義了,所以也可以直接拿來做計算,就算是時間單位不同,也不會有問題。 + +下面就是一個簡單的例子: +```cpp +std::chrono::minutes t1( 10 ); +std::chrono::seconds t2( 60 ); +std::chrono::seconds t3 = t1 - t2; +std::cout << t3.count() << " second" << std::endl; +``` + +其中,t1 是代表 10 分鐘、 t2 是代表 60 秒,t3 則是 t1 減去 t2,也就是 600 – 60 = 540 秒。 + +而如果要取得一個 duration 的值的話,則是要呼叫他的 count() 這個函式;像在上面的例子裡面,就會把 t3 的值輸出,所以最後會出現「540 second」。 + +而如果想要做強制的時間單位轉換,也可以使用 duration_cast<>() 這個函式來做;下面就是一個把以秒為單位的 t3 轉換成分鐘後再輸出。 +```cpp +cout << chrono::duration_cast( t3 ).count() << endl; +``` + +## time_point +相較於 duration 是用來紀錄時間的長度的,time_point 是用來記錄一個特定時間點的資料類別。他一樣是一個 template class,需要指定要使用的 clock 與時間單位(duration)。 + +Chrono 一般來說有提供兩種 clock 可以使用,分別是:system_clock 和 steady_clock。其中 system_clock 是直接去抓系統的時間,有可能在使用中會被被修改([參考](http://en.cppreference.com/w/cpp/chrono/system_clock));而 steady_clock 則是確實地去紀錄時間的流逝,所以不會出現時間倒退的狀況([參考](http://en.cppreference.com/w/cpp/chrono/steady_clock))。 + +一般要使用的話,大概會是下面的樣子: +```cpp +std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); +std::cout << "Hello World\n"; +std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now(); +std::cout << "Printing took " + << std::chrono::duration_cast(t2 - t1).count() + << "us.\n"; +``` + +透過 clock 類別所提供的 now() 這個函式,可以快速地取得現在的時間;而兩者相減的話,則會產生一個型別為 duration 的結果;在上面的例子裡面,就是一開始先取得當下的時間 t1,然後輸出一個字串後、再去取得一個時間 t2,之後兩者相減,就可以取得中間過程所花費的時間了。在這邊則是在相減後,把結果轉換成以 micro second 為單位後,再做輸出。 + +而 time_point 也可以和 duration 做計算,得出新的 time_point;例如下面的程式碼,就是計算 10 個小時候的時間: +```cpp +std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); +std::chrono::system_clock::time_point nt = now + std::chrono::hours(10); +``` +另外,chrono 也有定義 high_resolution_clock,提供更高的精確度([參考](http://en.cppreference.com/w/cpp/chrono/high_resolution_clock));但是實際上在 MSVC11 上,他就等同於 system_clock。 + +而如果要把不同定義的 time_point 做轉換,則也可以使用 time_point_cast<>() 這個函式來處理,不過這邊就不多加說明了。 + +## time_point 的輸出 +STL 的 chrono 並沒有定義 time_point 的輸出方式,所以我們並不能直接透過 output stream 來輸出 time_point 的資料,所以如果要把他輸出成字串的話,其實還有點麻煩… + +如果想要輸出的話,一個方法是透過 clock 提供的 to_time_t() 這個函式,把 time_point 先把他轉換成 C-style 的 time_t,然後再透過 ctime() 這類的函式做輸出;下面是一個簡單的範例: +```cpp +std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); +std::time_t now_c = std::chrono::system_clock::to_time_t( now ); +std::cout << std::ctime( &now_c ) << std::endl; +``` + +而如果是使用 Boost 的版本的話,Boost 則是另外有提供 chrono_io.hpp 這個檔案,在裡面替 duration 和 time_point 定義了輸出的格式,可以直接使用,相當地方便~有興趣的話,可以參考 [Boost 的官方說明](http://www.boost.org/doc/libs/1_55_0/doc/html/chrono/users_guide.html#chrono.users_guide.tutorial.i_o)。 + +## 參考來源 +- [C++11 STL 的時間函式庫:chrono – Heresy's Space](https://kheresy.wordpress.com/2013/12/27/c-stl-chrono/) \ No newline at end of file