我正在解析文档并写入磁盘对,例如:
0 vs 1, true 0 vs 2, false 0 vs 3, true 1 vs 2, true 1 vs 3, false ..
等等。
接下来我通过删除随机行(如果它们超出的值具有真值,并且反之亦然)来平衡每个实例的trues和falses行,并且我最终得到一个像这样的文件:
0 vs 1 true 0 vs 2 false 1 vs 2 true 1 vs 3 true 1 vs 4 false 1 vs 5 false
这些谬误通常远远超过真实,所以在前面的例子中,我只能为isntance 0保留1个假,而对于1个实例只有2个falses。
在解析然后平衡之前,我分两个步骤完成此过程。
现在,我的问题是不平衡文件太大:超过1GB,其大部分行将通过平衡步骤删除。
我的问题是:我可以在解析时平衡行吗?
我的猜测是否定的,因为我不知道哪些项目到达,并且在找到特定实例的所有行之前我无法删除任何行。
我希望很清楚。 感谢
答案 0 :(得分:0)
听起来你只需要一次加载一个实例的数据,你只需要为每个实例值记录一个数字和一个布尔值。
我建议您在实例编号更改(或文件结束)之前读取数据。这应该远远小于1 GB并修复内存。
如果使用TIntArrayList(或int [])和BitSet,这将更有效地存储数据。您可以在处理每个实例后清除它们。
编辑:如果数据是随机排列的,您可能需要读取一次文件以计算每个实例的真/假数,然后再次读取该文件以生成结果。
另一种选择是尝试以不同的方式将整个文件加载到内存中。您应该能够以此格式加载1 GB的数据,并使其使用少于1 GB。
您需要了解如何最大限度地减少每行数据的开销,并且可以显着降低消耗。
class Row { // uses a total of 80 bytes in a 32-bit JVM
// 16 byte header
Integer x; // 4 + 24 bytes.
Integer y; // 4 + 24 bytes.
Boolean b; // 1 byte
// 7 bytes of padding.
}
class Row { // uses a total of 32 bytes in a 32-bit JVM
// 16 byte header
int x; // 4 bytes.
int y; // 4 bytes.
boolean b; // 1 byte
// 7 bytes of padding.
}
class Rows { // uses a total of 8-9 bytes/row
// 16 byte header
int[] x; // 4 bytes/row, TIntArrayList is easier to use.
int[] y; // 4 bytes/row
BitSet b; // 1 bit/row
// 7 bytes of padding.
}
// if your numbers are between -32,768 and 32,767
class Rows { // uses a total of 4-5 bytes/row
// 16 byte header
short[] x; // 4 bytes/row, TShortArrayList is easier to use.
short[] y; // 4 bytes/row
BitSet b; // 1 bit/row
// 7 bytes of padding.
}
答案 1 :(得分:0)
一些想法 -
1)如果文件是1GB,您可以将其加载到数据结构中,但您可能已经尝试过这个 2)如果按行对数据进行排序或分组,则可以读取每一行,直到找到新行并重新平衡 3)如果数据未排序,您可以使用随机访问IO类对文件进行就地排序,然后执行2) 4)如果那是不可能的,你总是可以对文件中的每一行进行多次传递,这显然会很慢。
答案 2 :(得分:0)
如果您使用轻量级数据库 - 德比,h2等会发生什么?我想你可以编写排序,过滤等查询来达到你想要的......