Skip to content

Commit d2704fb

Browse files
committed
1
1 parent d8f24c1 commit d2704fb

File tree

11 files changed

+1296
-60
lines changed

11 files changed

+1296
-60
lines changed

stlseries/stl_map/.vim_localrc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ func! MarkPG()
1010
let [mark_lnum, mark_col] = searchpos('^<!-- PG\d\+ -->$', 'nW')
1111
let [lnum, col] = searchpos('^---\n\n', 'nW')
1212
if mark_lnum == 0 || (lnum != 0 && mark_lnum > lnum)
13-
exec 'norm! o\n<!-- PG'.pgidx.' -->'
13+
exec 'norm! o'
14+
exec 'norm! o<!-- PG'.pgidx.' -->'
1415
if lnum != 0
1516
let lnum = lnum + 2
1617
endif
1718
else
18-
exec 'norm! '.mark_lnum.'G0ddc$\n<!-- PG'.pgidx.' -->'
19+
exec 'norm! '.mark_lnum.'G0c$<!-- PG'.pgidx.' -->'
1920
endif
2021
let pgidx = pgidx + 1
2122
endwhile
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#pragma once
2+
3+
#include <chrono>
4+
#include <iostream>
5+
#include <vector>
6+
#include <iomanip>
7+
#include <string_view>
8+
#include <map>
9+
#include <set>
10+
11+
class ScopeProfiler {
12+
public:
13+
using ClockType = std::chrono::high_resolution_clock;
14+
15+
struct Record {
16+
const char *tag;
17+
int us;
18+
};
19+
20+
private:
21+
inline thread_local static std::vector<Record> records;
22+
23+
ClockType::time_point beg;
24+
ClockType::time_point end;
25+
const char *tag;
26+
27+
inline ScopeProfiler(const char *tag, ClockType::time_point beg);
28+
inline void onDestroy(ClockType::time_point end);
29+
30+
public:
31+
ScopeProfiler(const char *tag_) : ScopeProfiler(tag_, ClockType::now()) {}
32+
~ScopeProfiler() { onDestroy(ClockType::now()); }
33+
34+
static std::vector<Record> const &getRecords() { return records; }
35+
inline static void printLog(std::ostream &out = std::cout);
36+
};
37+
38+
ScopeProfiler::ScopeProfiler(const char *tag_, ScopeProfiler::ClockType::time_point beg_)
39+
: beg(beg_), tag(tag_)
40+
{
41+
}
42+
43+
void ScopeProfiler::onDestroy(ScopeProfiler::ClockType::time_point end) {
44+
auto diff = end - beg;
45+
int us = std::chrono::duration_cast<std::chrono::microseconds>(diff).count();
46+
records.push_back({tag, us});
47+
}
48+
49+
void ScopeProfiler::printLog(std::ostream &out) {
50+
if (records.size() == 0) {
51+
return;
52+
}
53+
54+
struct Statistic {
55+
int max_us = 0;
56+
int min_us = 0;
57+
int total_us = 0;
58+
int count_rec = 0;
59+
const char *tag = nullptr;
60+
};
61+
std::map<std::string_view, Statistic> stats;
62+
for (auto const &[tag, us]: records) {
63+
auto &stat = stats[tag];
64+
stat.total_us += us;
65+
stat.max_us = std::max(stat.max_us, us);
66+
stat.min_us = !stat.count_rec ? us : std::min(stat.min_us, us);
67+
stat.count_rec++;
68+
stat.tag = tag;
69+
}
70+
71+
struct StatisticCompare {
72+
using value_type = std::pair<std::string_view, Statistic>;
73+
bool operator()(value_type const &lhs, value_type const &rhs) const {
74+
return lhs.second.total_us > rhs.second.total_us;
75+
}
76+
};
77+
78+
std::multiset<std::pair<std::string_view, Statistic>, StatisticCompare> sortstats(stats.begin(), stats.end());
79+
80+
auto dump = [&out] (int val, int w) {
81+
auto tpwv = 1;
82+
for (int i = 0; i < w - 1; i++) tpwv *= 10;
83+
if (val > tpwv) {
84+
if (val / 1000 > tpwv / 10) {
85+
out << std::setw(w - 1) << val / 1000000 << 'M';
86+
} else {
87+
out << std::setw(w - 1) << val / 1000 << 'k';
88+
}
89+
} else {
90+
out << std::setw(w) << val;
91+
}
92+
};
93+
94+
out << " avg | min | max | total | cnt | tag\n";
95+
for (auto const &[tag, stat]: sortstats) {
96+
dump(stat.total_us / stat.count_rec, 9); out << '|';
97+
dump(stat.min_us, 9); out << '|';
98+
dump(stat.max_us, 9); out << '|';
99+
dump(stat.total_us, 9); out << '|';
100+
dump(stat.count_rec, 5); out << '|';
101+
out << ' ' << tag << '\n';
102+
}
103+
}
104+
105+
#if defined(__GUNC__) || defined(__clang__)
106+
#define DefScopeProfiler ScopeProfiler _scopeProfiler(__PRETTY_FUNCTION__);
107+
#elif defined(_MSC_VER)
108+
#define DefScopeProfiler ScopeProfiler _scopeProfiler(__FUNCSIG__);
109+
#else
110+
#define DefScopeProfiler ScopeProfiler _scopeProfiler(__func__);
111+
#endif
112+
113+
template <class T>
114+
static
115+
#if defined(__GUNC__) || defined(__clang__)
116+
__attribute__((noinline))
117+
#elif defined(_MSC_VER)
118+
__declspec(noinline)
119+
#endif
120+
void doNotOptimize(T volatile const &t) {}
121+
122+
static void printScopeProfiler(std::ostream &out = std::cout) {
123+
ScopeProfiler::printLog(out);
124+
}

stlseries/stl_map/experiment/a.cpp

Lines changed: 0 additions & 5 deletions
This file was deleted.

stlseries/stl_map/experiment/main.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,17 @@
22
#include "print.h"
33
#include "cppdemangle.h"
44
#include "map_get.h"
5+
#include "ScopeProfiler.h"
56
using namespace std;
67

78
int main() {
8-
map<string, string> msg = {
9-
{"hello", "world"},
10-
{"fuck", "rust"},
9+
struct MyData {
10+
int value;
11+
explicit MyData(int value_) : value(value_) {}
1112
};
12-
print(msg);
13-
if (msg.count("fuck")) {
14-
print("存在fuck,其值为", msg.at("fuck"));
15-
} else {
16-
print("找不到fuck");
17-
}
18-
if (msg.count("suck")) {
19-
print("存在suck,其值为", msg.at("suck"));
20-
} else {
21-
print("找不到suck");
22-
}
13+
map<string, unique_ptr<MyData>> m;
14+
m.insert({"answer", make_unique<MyData>(42)});
15+
m.insert({"fuck", make_unique<MyData>(985)});
16+
print(m.at("answer")->value); // 42
2317
return 0;
2418
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <bits/stdc++.h>
2+
#include "print.h"
3+
#include "cppdemangle.h"
4+
#include "map_get.h"
5+
#include "ScopeProfiler.h"
6+
using namespace std;
7+
8+
struct MyClass {
9+
int arr[4096];
10+
};
11+
12+
template <class K, class V>
13+
static void test_insert(map<K, V> &tab) {
14+
DefScopeProfiler;
15+
for (int i = 0; i < 1000; i++) {
16+
tab.insert({i, {}});
17+
}
18+
}
19+
20+
template <class K, class V>
21+
static void test_try_emplace(map<K, V> &tab) {
22+
DefScopeProfiler;
23+
for (int i = 0; i < 1000; i++) {
24+
tab.try_emplace(i);
25+
}
26+
}
27+
28+
int main() {
29+
map<
30+
return 0;
31+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <bits/stdc++.h>
2+
#include "print.h"
3+
#include "cppdemangle.h"
4+
#include "map_get.h"
5+
#include "ScopeProfiler.h"
6+
using namespace std;
7+
8+
struct RAII {
9+
int i;
10+
11+
explicit RAII(int i_) : i(i_) {
12+
printf("%d号资源初始化\n", i);
13+
}
14+
15+
RAII(RAII &&) noexcept {
16+
printf("%d号资源移动\n", i);
17+
}
18+
19+
RAII &operator=(RAII &&) noexcept {
20+
printf("%d号资源移动赋值\n", i);
21+
return *this;
22+
}
23+
24+
~RAII() {
25+
printf("%d号资源释放\n", i);
26+
}
27+
};
28+
29+
int main() {
30+
{
31+
map<string, RAII> m;
32+
m.try_emplace("资源1号", 1);
33+
m.try_emplace("资源2号", 2);
34+
m.erase("资源1号");
35+
m.try_emplace("资源3号", 3);
36+
}
37+
printf("此时所有资源都应该已经释放\n");
38+
return 0;
39+
}

stlseries/stl_map/images/logicmap.png

34.2 KB
Loading

stlseries/stl_map/images/physmap.png

51.7 KB
Loading

stlseries/stl_map/images/setvsmap.png

13 KB
Loading
6.95 KB
Loading

0 commit comments

Comments
 (0)