我有一个任务,我知道如何编码(在C#中), 但我知道一个简单的实现将无法满足我的所有需求。 所以,我正在寻找可能满足我所有需求的技巧。
我正在编写一个涉及N个实体随时间交互的模拟。
N将从30左右开始,然后进入数千人。
a. The number of entities will change during the course of the simulation.
湾我希望这将要求每个实体都有自己的跟踪文件。
每个实体至少有20个参数,最多可达数百万;我想跟踪一段时间。
一个。这很可能要求我们不能始终将所有值保留在内存中。有些子集应该没问题。
湾每个实体的参数数量最初将是固定的,但我可以想到一些测试会使参数数量随着时间的推移而变慢。
模拟将持续数百万个时间步,我需要保留每个参数的每个值。
我将使用这些痕迹:
一个。绘制参数的子集(可配置),持续从当前时间步长到过去的固定时间量。
i. Normally on the order of 300 time steps.
ii. These plots are in real time while the simulation is running.
湾我将使用这些迹线重新进行模拟,因此我需要在给定时间步骤快速访问所有参数,以便我可以在模拟中快速移动到不同的时间。
i. This requires the values be stored in a file(s) which can be inspected/loaded after restarting the software.
ii. Using a database is NOT an option.
℃。我将使用后续分析的参数,我无法预先定义,因此需要一个更灵活的系统。
我最初的想法:
每个实体包含所有参数的一个类。
由内存映射文件支持。
只有固定但移动的文件数量才会映射到主内存
第二个内存映射文件,它将时间索引保存到主文件,以便在重新播放模拟期间更快地访问。这可能非常重要,因为每个实体文件将代表完整模拟的不同时间片。
答案 0 :(得分:3)
我会从SQLite开始。 SQLite就像一个二进制格式库,您可以方便快捷地查询。 不非常像数据库,因为您可以在任何机器上运行它,无需任何安装。
我强烈建议不要使用XML,因为需要数百万个步骤,可能需要数百万个参数。
编辑:鉴于涉及的数据量庞大,SQLite最终可能对您来说太慢了。不要误会我的意思,SQLite非常快,但它不会打败搜索和读取,看起来你的用例是基本的二进制IO是相当合适的。
如果你使用二进制IO方法,你应该期待一些适度的编码,并且如果应用程序中途死亡,你的文件就会保持一致的状态,除非你专门编写这样的代码,否则不存在这样的细节。 / p>
答案 1 :(得分:2)
KISS - 只需为每个实体编写一个日志文件,并在每个时间片以指定的顺序写出每个参数(因此,不要通过添加参数名称来使日志文件的大小加倍)。如果要指定每列的参数名称和实体的标识,则可以在每个日志文件中包含标头。
如果有许多参数值在模拟过程中保持固定或缓慢变化,您可以将这些参数值写入另一个仅编码参数值更改的文件,而不是每个时间片的每个值。
您可能应该同步日志记录,以便使用相同的时间值写出每个日志条目。而不是通过中心文件进行协调,只需将文件每行中的第一个值设为时间值。
忘记数据库 - 模拟重放目的太慢和太多开销。对于模拟的重放,您只需要对每个时间片进行顺序访问,只需逐个读取文件行,即可最有效,最快速地实现。
出于同样的原因 - 速度和空间效率 - 忘记XML。
答案 2 :(得分:1)
仅供记忆部分......
1.您可以将数据保存为xElemet(很抱歉对linq不太了解)但它拥有XML逻辑。
2.保留记录柜台。
在n条记录之后将xelement保存到xmlFile(data1.xml,... dataN.xml)
对于您喜欢的任何逻辑,它可以是一个完美的日志:
<run>
<step id="1">
<param1 />
<param2 />
<param3 />
</step>
.
.
.
<step id="N">
<param1 />
<param2 />
<param3 />
</step>
</run>
这样你的内存是免费的,而且数据相对免费。 您不必过多考虑数据库问题,LINQ可以为您做的事情非常棒......只需打开当前的XML日志文件...
答案 3 :(得分:0)
这是我现在正在做的事情
int bw = 0;
private void timer1_Tick(object sender, EventArgs e)
{
bw = Convert.ToInt32(lblBytesReceived.Text) - bw;
SqlCommand comnd = new SqlCommand("insert into tablee (bandwidthh,timee) values (" + bw.ToString() + ",@timee)", conn);
conn.Open();
comnd.Parameters.Add("@timee",System.Data.SqlDbType.Time).Value = DateTime.Now.TimeOfDay;
comnd.ExecuteNonQuery();
conn.Close();
}