टपल और संरचना के बारे में हमारी समान चर्चा है और मैं टपल और संरचना के बीच प्रदर्शन के अंतर की पहचान करने के लिए अपने एक सहयोगी की मदद से कुछ सरल बेंचमार्क लिखता हूं। हम पहले एक डिफ़ॉल्ट संरचना और एक ट्यूपल के साथ शुरू करते हैं।
struct StructData {
int X;
int Y;
double Cost;
std::string Label;
bool operator==(const StructData &rhs) {
return std::tie(X,Y,Cost, Label) == std::tie(rhs.X, rhs.Y, rhs.Cost, rhs.Label);
}
bool operator<(const StructData &rhs) {
return X < rhs.X || (X == rhs.X && (Y < rhs.Y || (Y == rhs.Y && (Cost < rhs.Cost || (Cost == rhs.Cost && Label < rhs.Label)))));
}
};
using TupleData = std::tuple<int, int, double, std::string>;
तब हम अपनी सरल संरचना और टपल के प्रदर्शन की तुलना करने के लिए सेलेरो का उपयोग करते हैं। नीचे gcc-4.9.2 और clang-4.0.0 का उपयोग करके बेंचमार्क कोड और प्रदर्शन परिणाम एकत्र किए गए हैं:
std::vector<StructData> test_struct_data(const size_t N) {
std::vector<StructData> data(N);
std::transform(data.begin(), data.end(), data.begin(), [N](auto item) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, N);
item.X = dis(gen);
item.Y = dis(gen);
item.Cost = item.X * item.Y;
item.Label = std::to_string(item.Cost);
return item;
});
return data;
}
std::vector<TupleData> test_tuple_data(const std::vector<StructData> &input) {
std::vector<TupleData> data(input.size());
std::transform(input.cbegin(), input.cend(), data.begin(),
[](auto item) { return std::tie(item.X, item.Y, item.Cost, item.Label); });
return data;
}
constexpr int NumberOfSamples = 10;
constexpr int NumberOfIterations = 5;
constexpr size_t N = 1000000;
auto const sdata = test_struct_data(N);
auto const tdata = test_tuple_data(sdata);
CELERO_MAIN
BASELINE(Sort, struct, NumberOfSamples, NumberOfIterations) {
std::vector<StructData> data(sdata.begin(), sdata.end());
std::sort(data.begin(), data.end());
}
BENCHMARK(Sort, tuple, NumberOfSamples, NumberOfIterations) {
std::vector<TupleData> data(tdata.begin(), tdata.end());
std::sort(data.begin(), data.end());
}
क्लैंग-4.0.0 के साथ एकत्र किए गए प्रदर्शन के परिणाम
Celero
Timer resolution: 0.001000 us
-----------------------------------------------------------------------------------------------------------------------------------------------
Group | Experiment | Prob. Space | Samples | Iterations | Baseline | us/Iteration | Iterations/sec |
-----------------------------------------------------------------------------------------------------------------------------------------------
Sort | struct | Null | 10 | 5 | 1.00000 | 196663.40000 | 5.08 |
Sort | tuple | Null | 10 | 5 | 0.92471 | 181857.20000 | 5.50 |
Complete.
और प्रदर्शन परिणाम gcc-4.9.2 का उपयोग करके एकत्र किया गया
Celero
Timer resolution: 0.001000 us
-----------------------------------------------------------------------------------------------------------------------------------------------
Group | Experiment | Prob. Space | Samples | Iterations | Baseline | us/Iteration | Iterations/sec |
-----------------------------------------------------------------------------------------------------------------------------------------------
Sort | struct | Null | 10 | 5 | 1.00000 | 219096.00000 | 4.56 |
Sort | tuple | Null | 10 | 5 | 0.91463 | 200391.80000 | 4.99 |
Complete.
उपरोक्त परिणामों से हम स्पष्ट रूप से देख सकते हैं
ट्यूल एक डिफ़ॉल्ट संरचना से तेज है
क्लैंग द्वारा बाइनरी प्रोडक्शन में उच्च प्रदर्शन है जो कि जीसीसी का है। क्लैंग-बनाम-जीसीसी इस चर्चा का उद्देश्य नहीं है, इसलिए मैं विस्तार से गोता नहीं लगाऊंगा।
हम सभी जानते हैं कि प्रत्येक एकल संरचना परिभाषा के लिए एक == या <या> ऑपरेटर लिखना एक दर्दनाक और छोटी गाड़ी का काम होगा। हमारे कस्टम तुलनित्र को std :: टाई और फिर से हमारे बेंचमार्क का उपयोग करने दें।
bool operator<(const StructData &rhs) {
return std::tie(X,Y,Cost, Label) < std::tie(rhs.X, rhs.Y, rhs.Cost, rhs.Label);
}
Celero
Timer resolution: 0.001000 us
-----------------------------------------------------------------------------------------------------------------------------------------------
Group | Experiment | Prob. Space | Samples | Iterations | Baseline | us/Iteration | Iterations/sec |
-----------------------------------------------------------------------------------------------------------------------------------------------
Sort | struct | Null | 10 | 5 | 1.00000 | 200508.20000 | 4.99 |
Sort | tuple | Null | 10 | 5 | 0.90033 | 180523.80000 | 5.54 |
Complete.
अब हम देख सकते हैं कि std :: टाई का उपयोग हमारे कोड को अधिक सुरुचिपूर्ण बनाता है और गलती करना कठिन है, हालांकि, हम लगभग 1% प्रदर्शन को ढीला कर देंगे। मैं अब के लिए std :: टाई सॉल्यूशन के साथ रहूंगा क्योंकि मुझे भी स्वनिर्धारित तुलनित्र के साथ फ्लोटिंग पॉइंट नंबरों की तुलना करने के बारे में एक चेतावनी मिलती है।
अब तक हमारे पास हमारे संरचना कोड को तेजी से चलाने के लिए कोई समाधान नहीं है। आइए हम स्वैप समारोह पर एक नज़र डालें और इसे फिर से लिखें कि क्या हम कोई प्रदर्शन हासिल कर सकते हैं:
struct StructData {
int X;
int Y;
double Cost;
std::string Label;
bool operator==(const StructData &rhs) {
return std::tie(X,Y,Cost, Label) == std::tie(rhs.X, rhs.Y, rhs.Cost, rhs.Label);
}
void swap(StructData & other)
{
std::swap(X, other.X);
std::swap(Y, other.Y);
std::swap(Cost, other.Cost);
std::swap(Label, other.Label);
}
bool operator<(const StructData &rhs) {
return std::tie(X,Y,Cost, Label) < std::tie(rhs.X, rhs.Y, rhs.Cost, rhs.Label);
}
};
क्लेंग-4.0.0 का उपयोग करके प्रदर्शन परिणाम एकत्र किए गए
Celero
Timer resolution: 0.001000 us
-----------------------------------------------------------------------------------------------------------------------------------------------
Group | Experiment | Prob. Space | Samples | Iterations | Baseline | us/Iteration | Iterations/sec |
-----------------------------------------------------------------------------------------------------------------------------------------------
Sort | struct | Null | 10 | 5 | 1.00000 | 176308.80000 | 5.67 |
Sort | tuple | Null | 10 | 5 | 1.02699 | 181067.60000 | 5.52 |
Complete.
और प्रदर्शन परिणाम gcc-4.9.2 का उपयोग करके एकत्र किया गया
Celero
Timer resolution: 0.001000 us
-----------------------------------------------------------------------------------------------------------------------------------------------
Group | Experiment | Prob. Space | Samples | Iterations | Baseline | us/Iteration | Iterations/sec |
-----------------------------------------------------------------------------------------------------------------------------------------------
Sort | struct | Null | 10 | 5 | 1.00000 | 198844.80000 | 5.03 |
Sort | tuple | Null | 10 | 5 | 1.00601 | 200039.80000 | 5.00 |
Complete.
अब हमारी संरचना एक टपल की तुलना में थोड़ी तेज है (क्लैंग के साथ लगभग 3% और जीसीसी के साथ 1% से कम), हालांकि, हमें अपनी सभी संरचनाओं के लिए अपने अनुकूलित स्वैप फ़ंक्शन को लिखने की आवश्यकता है।
tuple
परिभाषा परिभाषित है, इसलिए यह आपके कार्यान्वयन पर निर्भर करता है। व्यक्तिगत रूप से, मैं इस पर भरोसा नहीं करूंगा ।