原文地址:https://www.cnblogs.com/sdflysha/p/20190821-generate-lorem-data.htmlhtml
在演示Demo、数据库脱敏、性能测试中,有时须要生成大量随机数据。Bogus
就是.NET
中优秀的高性能、合理、支持多语言的随机数据生成库。git
Bogus
的Github
连接:https://github.com/bchavez/Bogus,图标以下:github
Bogus
目前Bogus
最新版是28.0.2
,本文演示基本该版本,不保证官方之后会不会修改本文的使用方式。shell
使用Powershell
:数据库
PM> Install-Package Bogus -Version 28.0.2
或者使用PackageReference
:json
<PackageReference Include="Bogus" Version="28.0.2" />
个人数据生成代码以下(代码使用LINQPad
运行,能够几乎复制到Visual Studio
中运行,效果同样,其中.Dump()
是LINQPad
特有方法):缓存
void Main() { var userGenerator = new Faker<User>() .RuleFor(x => x.Id, x => x.IndexFaker + 1) .RuleFor(x => x.Gender, x => x.Person.Gender) .RuleFor(x => x.FirstName, (x, u) => x.Name.FirstName(u.Gender)) .RuleFor(x => x.LastName, (x, u) => x.Name.LastName(u.Gender)) .RuleFor(x => x.Email, (x, u) => x.Internet.Email(u.FirstName, u.LastName)) .RuleFor(x => x.BirthDate, x => x.Person.DateOfBirth) .RuleFor(x => x.Company, x => x.Person.Company.Name) .RuleFor(x => x.Phone, x => x.Person.Phone) .RuleFor(x => x.Website, x => x.Person.Website) .RuleFor(x => x.SSN, x => x.Person.Ssn()); userGenerator.GenerateForever().Take(10).Dump(); } class User { public int Id { get; set; } public Bogus.DataSets.Name.Gender Gender { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public DateTime BirthDate { get; set; } public string Company { get; set; } public string Phone { get; set; } public string Website { get; set; } public string SSN { get; set; } }
生成的数据如图所示:性能
注意细节,姓名FirstName
/LastName
是会根据性别Gender
来随机生成的,而后邮箱Email
字段也会根据FirstName
/LastName
来相应地生成,并不是彻底随机,毫无规律。这些规则是经过.RuleFor()
第二个回调的第二个字段来决定的:测试
.RuleFor(x => x.FirstName, (x, u) => x.Name.FirstName(u.Gender)) // 根据Gender生成FirstName .RuleFor(x => x.LastName, (x, u) => x.Name.LastName(u.Gender)) // 根据Gender生成LastName .RuleFor(x => x.Email, (x, u) => x.Internet.Email(u.FirstName, u.LastName)) // 根据姓名生成邮箱
最后的.GenerateForever
返回了一个IEnumerable<User>
,是一个状态机,能够永久生成数据。spa
Bogus
也提供了一次性生成缓存数据的方法:List<User> Generate(int count)
。但因为我可能将这些数据作从此博客文章的性能测试原始数据,数据量可能会很是大,若是将这些数据缓存起来将很是浪费内存,而且影响性能。所以本例中我使用GenerateForever
来生成原始数据。
经过.NET Core 3.0
最新提供的System.Text.Json
里面的JsonSerializer
和Utf8JsonWriter
,我可能以极其高效的方法将这些测试数据序列化为JSON
,而后保存到磁盘中:
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\test-data.json"; using var file = File.Create(path); using var writer = new Utf8JsonWriter(file, new JsonWriterOptions { Indented = true }); var data = userGenerator.GenerateForever().Take(6_0000); JsonSerializer.Serialize(writer, data); Process.Start("explorer", @$"/select, ""{path}""".Dump()); // 资源管理器打开test-data.json文件夹
最后示例数据以下:
一共6万条数据,每条数据有10个字段,test-data.json
共19,166 KB
。
能够用以下代码将这6万条数据加载到.NET内存:
void Main() { string path = @"C:\Users\sdfly\Desktop\test-data\test-data.json"; byte[] bytes = File.ReadAllBytes(path); var users = JsonSerializer.Deserialize<List<User>>(bytes); // 数据分析演示 users.GroupBy(x => x.Email[x.Email.IndexOf('@')..]) .Select(x => new { Host = x.Key, Count = x.Count() }) .Dump(); } class User { public int Id { get; set; } public int Gender { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public DateTime BirthDate { get; set; } public string Company { get; set; } public string Phone { get; set; } public string Website { get; set; } public string SSN { get; set; } }
结果以下:
全部邮件都是hotmail.com
/gmail.com
/yahoo.com
三种邮箱的均匀分布,每种大约都在20000左右。