我想實現的寫作類型擦除的數據結構和 讀取任何類型的大數組列表中,具有以下 要求:實現快速寫一個類型擦除列表/讀
- 快速插入批量數據(接收
std::vector<T>
,其中T是原始類型)。 - 如果類型匹配,快速讀取所有/最新值
- 如果類型不匹配,則讀取/轉換。在從原始社會到原語(如雙>浮動,內部 - >雙)大多數情況下
我在想的接口將是這個樣子:
class Trace {
template<typename T> std::vector<T> read();
template<typename T> std::vector<T> latest();
template<typename T> void append(std::vector<T> values);
template<typename T> void replace(std::vector<T> values);
void clear();
};
,然後在使用TraceHandler類(單件結構),它允許訪問每個鍵的痕跡:
class TraceHandler {
public:
template<typename T>
std::vector<T> read(std::string const& key);
template<typename T>
void write(std::string const& key, std::vector<T> const& val);
private:
// STore all Traces for different types
};
而一個使用率會是這個樣子:
TraceHandler th;
std::vector<double> vals(1000,1.0), res;
th.write("values",vals);
std::vector<int> resInt;
res = th.read<double>("values");
resInt = th.read<int>("values");
我們當前的實現爲每個數據類型創建一個跟蹤和 用戶必須保持正確的類型,這是賽道不是很靈活 (如編寫使用writeDouble()
,讀取使用readDouble
)。
我的第一種方法是內部存儲 載體的類型更改爲any
類型(我們使用波科庫,所以我是用 Poco::Any
和Poco::DynamicAny
),但是這會導致大 性能損失。
數據從設備寫入的高頻(數據被採集 與高達20kHz,然後被寫入到跟蹤的周圍4K塊), 和一個普通的向量之間所測量的性能差和任何之一 類型是因子500-1000(測量800ms與4ms,大 大容量插入/讀入循環)。由於 構造函數調用vs簡單的memcopy,大多數時間會丟失。
所以我的問題是:有沒有一種方法來實現這個接口(或 備選)具有良好的批量插入/讀取性能?
編輯: 這是當前實現我使用:
class LWDynamicVector
{
private:
typedef std::vector<Poco::DynamicAny> DataList;
DataList m_data;
public:
LWDynamicVector() {}
template<typename T> std::vector<T> read() {
return std::vector<T>(m_data.begin(),m_data.end());
}
template<typename T> void writeAppend(std::vector<T> v) {
m_data.insert(m_data.end(),v.begin(),v.end());
}
template<typename T> void writeReplace(std::vector<T> v) {
m_data.assign(v.begin(),v.end());
}
};
,我使用的測試:
TEST(DynamicVector,Performance) {
typedef double Type;
size_t runs = 100; size_t N = 20480;
std::vector<Type> input;
input.reserve(N);
for(size_t i = 0; i < N; ++i) {
input.push_back(rand());
}
{
OldVector<Type> instance;
Poco::Timestamp ts;
for(size_t i = 0; i < runs; ++i) {
instance.writeAppend(input);
}
std::cout << "Old vector: time elapsed(ms) = " << ts.elapsed()/1000.0 << std::endl;
std::vector<Type> output = instance.read();
EXPECT_EQ(output.back(),output.back());
}
{
LWDynamicVector dbv;
Poco::Timestamp ts;
for(size_t i = 0; i < runs; ++i) {
dbv.writeAppend(input);
}
std::cout << "New vector: time elapsed(ms) = " << ts.elapsed()/1000.0 << std::endl;
std::vector<Type> output = dbv.read<Type>();
EXPECT_EQ(output.back(),output.back());
}
}
導致:
Old vector: time elapsed(ms) = 44.004
New vector: time elapsed(ms) = 4380.44
關於c ompiler選項和優化:不幸的是,我被困在當前的設置中,沒有選擇來改變它們。在大多數情況下,構建以調試模式運行,但仍需滿足時序要求。但不管怎麼說,性能並不在釋放模式改進:
Old vector: time elapsed(ms) = 20.002
New vector: time elapsed(ms) = 1013.1
如何OldVector樣子?舊的也轉換類型?你在使用C++ 11嗎? – Surt 2014-10-01 11:38:08
@Surt目前'OldVector'只能存儲一種類型。特別是它是一個帶有鎖和新界面的'std :: vector'。目前我們並沒有使用C++ 11,但我會對使用C++ 11的任何解決方案感興趣。 –
MatthiasB
2014-10-01 11:41:46
是否爲同一次運行寫入相同類型的數據,例如,在同一次測量中沒有double和int的組合?沒有重複例如7個雙打,然後在同一個軌跡中有10個整數和3個字符串? – Surt 2014-10-01 12:13:14