我有一个任务,包括问题和带有对象的大型JSON文件。 JSON文件内部大约有500万个对象,并且具有303MB。
可以下载here这个大文件。
小预览里面的内容:
{ Reviewer:1, Movie:1535440, Grade:4, Date:'2005-08-18'},
{ Reviewer:1, Movie:1426604, Grade:4, Date:'2005-09-01'},
{ Reviewer:1, Movie:1815755, Grade:5, Date:'2004-07-20'},
{ Reviewer:2, Movie:2059652, Grade:4, Date:'2005-09-05'},
{ Reviewer:2, Movie:1666394, Grade:3, Date:'2005-04-19'},
{ Reviewer:2, Movie:1759415, Grade:4, Date:'2005-04-22'},
每一行代表一个评论。我们可以在此处找到评论者的ID,然后评分他用来评论电影的电影,电影ID和日期(以字符串形式)。
我需要将此文件导入到.NET Console应用程序中,反序列化并将其转换为对象,以便随后可以使用它们并创建一些方法,对象列表等。
问题示例:
- 使用参数N,来自评论者N的评论数是多少?
(这应该是带有评论者ID参数的方法,一个评论者(人)可以对不同电影进行多次评论)
- 哪些评论者评论最多?
问题是,每次我反序列化文件中的对象时,仅反序列化本身就需要10秒钟左右,而要求是,每种方法最多需要4秒钟的处理时间。 即使仅指定一个要从文件反序列化的字段,也要花费太多时间。
请问您知道一些有效的方法或某些nuGet软件包如何在不到4秒的时间内转换这些数据吗? 我只尝试了Newtonsoft.JSON。
我找到了一篇有趣的文章,但是我未能成功实现该代码,因为未完整描述代码片段,而且我无法弄清楚。这是该文章的link。
我会很感谢每一个想法和帮助。
答案 0 :(得分:3)
我决定尝试一下,因此我创建了一些代码,可以用来回答OP提出的两个示例问题。我能做的最好的就是在不到7秒的时间内得到结果,而不是OP要求的4:-(
以下方法返回文件中的所有审阅者ID。我正在使用JsonTextReader
仅提取Reviewer
属性的值,而没有反序列化整个json对象:
private static IEnumerable<long> GetReviewerIds(string path)
{
using (StreamReader streamReader = File.OpenText(path))
using (JsonTextReader reader = new JsonTextReader(streamReader))
{
reader.CloseInput = true;
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName && reader.Value.Equals("Reviewer"))
{
int? id = reader.ReadAsInt32();
if (id.HasValue)
{
yield return id.Value;
}
}
}
}
}
int reviewerId = 4;
var stopWatch = Stopwatch.StartNew();
int numberOfReviews = GetReviewerIds(@"ratings.json").Count(x => x == reviewerId);
stopWatch.Stop();
Console.WriteLine($"Number of reviews: {numberOfReviews}; Execution time: {stopWatch.Elapsed:g}");
输出:
评论数:142;执行时间:0:00:06.2137702
int numberOfReviewers = 3;
var stopWatch = Stopwatch.StartNew();
var reviewers = GetReviewerIds(@"ratings.json")
.GroupBy(x => x)
.Select(x => new
{
Id = x.Key,
Count = x.Count()
})
.OrderByDescending(x => x.Count)
.Take(numberOfReviewers)
.ToList();
stopWatch.Stop();
Console.WriteLine($"Reviewer with ID {reviewers.First().Id} has done {reviewers.First().Count} reviews; Execution time: {stopWatch.Elapsed:g}");
输出:
ID 571的审阅者完成了154832条评论;执行时间:0:00:06.1256635