专栏首页雪雁的专栏.NET如何生成大量随机数据

.NET如何生成大量随机数据

出处:本文转载于微信公众号【DotNet骚操作】,作者【周杰DotNet 】

前言

在演示Demo、数据库脱敏、性能测试中,有时需要生成大量随机数据。Bogus就是.NET中优秀的高性能、合理、支持多语言的随机数据生成库。

Bogus的Github链接:https://github.com/bchavez/Bogus,图标如下:

安装Bogus

目前Bogus最新版是28.0.2,本文演示基本该版本,不保证官方以后会不会修改本文的使用方式。

使用Powershell安装:

PM> Install-Package Bogus -Version 28.0.2

或者使用PackageReference:

<PackageReference Include="Bogus" Version="28.0.2" />

使用Bogus

我的数据生成代码如下(代码使用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>,是一个状态机,可以永久生成数据。

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左右。

我计划今后如需要做性能测试或者演示,将使用该文件作为基准数据,已经上传到Github,该文件可以从这里下载:https://github.com/sdcb/blog-data/tree/master/2019/20190821-generate-lorem-data。

出处:微信公众号【DotNet骚操作】 原文链接:https://www.cnblogs.com/sdflysha/p/20190821-generate-lorem-data.html

本文分享自微信公众号 - magiccodes(xl----0)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 高性能动态编译库Natasha发布1.0版本!

    对于开源贡献者,Emit和表达式树不是陌生的字眼,IL的动态特性为封装工作带来了极大的方便,会Emit的开发者可以说驾驭了大部分的高性能、高动态...

    心莱科技雪雁
  • .NET手撸绘制TypeScript类图——上篇

    近年来随着交互界面的精细化, TypeScript越来越流行,前端的设计也越来复杂,而 类图正是用简单的箭头和方块,反映对象与对象之间关系/依赖的好方式。许多工...

    心莱科技雪雁
  • 开源导入导出通用库Magicodes.ExporterAndImporter发布

    https://github.com/xin-lai/Magicodes.ExporterAndImporter

    心莱科技雪雁
  • ABP框架学习之——数据校验

    易兒善
  • Unity高级(1)-服务器与网络交互

    HTTP/1.1 200 OK // 包含了HTTP协议版本、状态码、状态英文名称 Server: Apache-Coyote/1.1 ...

    雷潮
  • Unity高级(1)-服务器与网络交互

    HTTP/1.1 200 OK // 包含了HTTP协议版本、状态码、状态英文名称 Server: Apache-Coyote/1.1 ...

    啦啦啦
  • 使用MongoDB存储访问者信息

    网站的访问者信息的存储一般都是海量的,通常使用关系数据库,现在NoSQL运动火热,满足这样的需求使用NoSQL数据库会更好,网站访问者信息主要是两个功能: 1、...

    张善友
  • C# 数据操作系列 - 14 深入探索SqlSugar

    在上一篇中,我们知道了如何使用SqlSugar,但是也只是简单的了解了如何使用,仿佛是套着镣铐行走,这明显不符合一个合格的程序员应有的素养。所以,这一篇我们将对...

    程序员小高
  • 将JSON字符串反序列化为指定的.NET对象类型

      关于将JSON字符串反序列化为指定的.NET对象类型数据常见的场景主要是关于网络请求接口,获取到请求成功的响应数据。本篇主要讲的的是如何通过使用Newton...

    追逐时光
  • 推荐一个代码自动完成的工具AutoCode

    本文转载:http://www.cnblogs.com/xiaoxiangfeizi/archive/2012/07/24/2605884.html

    跟着阿笨一起玩NET

扫码关注云+社区

领取腾讯云代金券