有一个小脚本可以从数据库中获取大量数据,并进行迭代计算。在这个计算中使用了大约2500行,所以它不是很大,但我的老板还是希望我对计算进行分区(作为练习)。
我的一般策略(我只是在黑暗中拍摄)是打到数据库,抓住前50行,计算这50行的每一步,存储最后一行(因为计算是迭代的) ),从数据库中获取接下来的50行并继续此过程,直到计算出数据库中的所有行为止。
对我的策略的想法?做这种事的任何提示?
答案 0 :(得分:1)
我会这样做。
代码可能看起来像这样。
public class Worker
{
private BlockingQueue<Message> m_Queue = new BlockingQueue<Message>();
public void Start()
{
var fetcher = new Thread(() => { Fetch(); });
var processor = new Thread(() => { Process(); });
fetcher.Start();
processor.Start();
}
public void Fetch()
{
while (true)
{
var packet = GetDataPacketFromDatabase();
if (packet != null)
{
var message = new Message();
message.Packet = packet;
m_Queue.Enqueue(message);
}
else
{
break; // Stop if there is nothing left to fetch.
}
}
}
public void Process()
{
while (true)
{
Message message = m_Queue.Dequeue();
if (message.Packet 1= null)
{
Accumulate(message.Packet);
}
else
{
break; // Stop if there is nothing left to process.
}
}
}
private void Accumulate(Packet p)
{
// Process the packet and accumulate the results.
}
}
我应该指出,除非你对返回的数据做了一些非常复杂的计算(通过我的例子中的Accumulate
方法),否则处理线程将缺乏工作并且大部分时间处于空闲状态。我怀疑在这种情况下,分区和并行化处理的整个前提最终会比仅仅获取所有2500行并连续处理它们慢。
答案 1 :(得分:1)
我在编程中学到的第一件事就是当你不知道如何编写代码时,首先写出你自己用来解决它的过程(算法),一步一步,然后看看如何将其转换为代码。
听起来像是一个很好的第一步,你可以写出如何在纸上解决问题 - 而不用担心分区问题。我知道你的问题不是那么微不足道,但我会用一个求和的例子。
要查找所有记录的总数,您需要记录0 +记录1 +记录2 + ... +记录2499 =总和。
随着这种情况下降,您可以继续查看是否可以对其进行分区。另外,这很容易做到,因为加法是关联的。分组操作,这是一个分区。
现在,如果你找不到手动分区计算的方法,那么尝试在代码中对它进行分区将很困难。
但是,我的第一步是手动完成,然后在那里寻找分区可能性。
答案 2 :(得分:0)
由于计算听起来并非如此,这是线程提供好处的完美示例。制作N个线程来计算T(总记录数)/ N记录。完成所有线程后,您可以执行一个步骤来组合每个线程生成的所有小计。
答案 3 :(得分:0)
在不知道计算性质的情况下,很难说。
当人们说分区时,通常暗示数据/进程可以并行化 - 不同的分区在某种程度上是独立的 - 因此每个分区都可以独立处理。
通常情况下,我不会想到2500行,并且类似这样的东西,我可能会在数据库中使用持久计算列,并在数据库中处理它,如果行被更改,可能会触发重新计算。当然,从数据库中提取行进行计算往往效率低于数据库可以存储该信息或在运行中计算它的效率。
答案 4 :(得分:-2)
听起来像数据库cursors(可能很慢)或while loop or other alternatives的作业。