我有一个新词典(Of String,Long()),有3,125,000个唯一(字符串)键。 我在密钥中分配了近10亿(935,984,413)个值(所有长整数),并为每个密钥填充long()数组。
这对于普通数据集来说效果很好而且非常快,让我们说1,5000,000个字符串键和500,000,000个Long值要分发,大约需要2个小时。
然而,对于上述数据集,一旦我获得了数据的中途,该过程运行速度极慢,目前的趋势可能永远不会完成......
我认为我的内存不足,应用程序使用5GB内存,我相信它现在受到我的系统限制(8GB内存)。
如何计算上述情况所需的内存量? 字符串Keys的大小平均约为5个字符。
谢谢!
答案 0 :(得分:4)
Long
数据类型各为8字节。对于string
,它更复杂。查看着名的Jon Skeet的post。
引用:
至少在当前的实现中,字符串占用20+(n / 2)* 4 bytes(将n / 2的值向下舍入)
(注意:在他的blog post中,他对此字符串计算有一些更新)
根据您的情况,您的5个字符string
中的每一个都会占用:
20 + (5/2) * 4 = 20 + 8 = 28 bytes
尽管如此,您可以通过仅计算有效数字来简化计算 - 在您的情况下是Long
,因为它的成员比string
多得多,而您的string
键是Long
小尺寸(5个字符)。
因此,如果您有1亿个Long
,那么您将只有大约8GB内存用于935,984,413 x 8 = 7,487,875,304
。其他一些开销+字符串不太重要,但至少需要8 GB(string
)。
在您的示例中,28 * 3,125,000 = 87.5 MB
将是:
string
因此Long()
和 var assembly = Assembly.GetExecutingAssembly();
var resourceName = "<ProjectName>.<FolderName>.UsersList.csv";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream))
{
var csv = new CsvReader(reader);
csv.Configuration.Delimiter = ",";
csv.Configuration.HasHeaderRecord = true;
csv.Configuration.IgnoreHeaderWhiteSpace = true;
csv.Configuration.IgnoreQuotes = false;
csv.Configuration.IsHeaderCaseSensitive = false;
csv.Configuration.ThrowOnBadData = true;
csv.Configuration.QuoteAllFields = true;
csv.Configuration.RegisterClassMap<UsersClassMap>();
csv.Configuration.IgnoreReadingExceptions = true;
csv.Configuration.SkipEmptyRecords = false;
List<User> records = csv.GetRecords<User>().ToList();
foreach (User user in records)
{
bt.Create(user.FFirstName, user.lastName, user.Description, user.Password, user.OU, user.Group);
}
}
}
public class User
{
public string FFirstName { get; set; }
public string LastName { get; set; }
public string Description { get; set; }
public string Password { get; set; }
public string OU { get; set; }
public string Group { get; set; }
}
public class UsersClassMap : CsvClassMap<User>
{
public UsersClassMap()
{
Map(x => x.FFirstName).Index(0).Name("FFirstName");
Map(x => x.LastName).Index(1).Name("LastName");
Map(x => x.Description).Index(2).Name("Description");
Map(x => x.Password).Index(3).Name("Password");
Map(x => x.OU).Index(4).Name("OU");
Map(x => x.Group).Index(5).Name("Group");
}
}