-
Notifications
You must be signed in to change notification settings - Fork 857
28810 edited this page Mar 4, 2019
·
41 revisions
FreeSql实现了强大功能的同时,性能没有受到影响,项目中使用反射或耗时的操作都经过了缓存处理。读取数据部分采用了ExpressionTree,使得FreeSql解析实体数据的速度与Dapper非常接近。
IFreeSql mysql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=100")
.UseLogger(new LoggerFactory().CreateLogger("FreeSql.MySql"))
//由于null会默认输出日志到控制台,影响测试结果。这里传入一个空的日志输出对象
.UseAutoSyncStructure(false)
//关闭自动迁移功能
.Build();
class Song {
public int Id { get; set; }
public string Title { get; set; }
public string Url { get; set; }
public DateTime Create_time { get; set; }
public bool Is_deleted { get; set; }
}
测试方法:运行两次,以第二次性能报告,避免了首个运行慢不公平的情况。
数量 | Query<Class> | Query<Tuple> | Query<dynamic> | |
---|---|---|---|---|
Dapper.Query(sql) | 131072 | 623.4959ms | 424.2411ms | 644.8897ms |
FreeSql.Query(sql) | 131072 | 647.0552ms | 577.3532ms | 944.7454ms |
FreeSql.ToList | 131072 | 622.8980ms | 435.3532ms | - |
FreeSql以微小的性能差距输了,原因是支持了更多的类型,某些类型解析需要Parse、递归或循环处理。
由于Dapper没有批量插入/更新/删除的功能,并且都是执行一条SQL命令,测试结果没有意义。
FreeSql批量插入使用的命令:INSERT INTO Song (...) VALUES(...),VALUES(...),VALUES(...)...
[Fact]
public void QueryEntity() {
var sb = new StringBuilder();
var time = new Stopwatch();
time.Restart();
List<Song> dplist1 = null;
using (var conn = g.mysql.Ado.MasterPool.Get()) {
dplist1 = Dapper.SqlMapper.Query<Song>(conn.Value, "select * from song").ToList();
}
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper");
time.Restart();
var t3 = g.mysql.Ado.Query<Song>("select * from song");
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {t3.Count}; ORM: FreeSql*");
}
[Fact]
public void QueryTuple() {
var sb = new StringBuilder();
var time = new Stopwatch();
time.Restart();
List<(int, string, string)> dplist2 = null;
using (var conn = g.mysql.Ado.MasterPool.Get()) {
dplist2 = Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from song").ToList();
}
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {dplist2.Count}; ORM: Dapper");
time.Restart();
var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song");
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*");
}
[Fact]
public void QueryDynamic() {
var sb = new StringBuilder();
var time = new Stopwatch();
time.Restart();
List<dynamic> dplist3 = null;
using (var conn = g.mysql.Ado.MasterPool.Get()) {
dplist3 = Dapper.SqlMapper.Query<dynamic>(conn.Value, "select * from song").ToList();
}
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {dplist3.Count}; ORM: Dapper");
time.Restart();
var t5 = g.mysql.Ado.Query<dynamic>("select * from song");
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {t3.Count}; ORM: FreeSql*");
}
[Fact]
public void QueryList() {
var sb = new StringBuilder();
var time = new Stopwatch();
time.Restart();
var t3 = g.mysql.Select<Song>().ToList();
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*");
time.Restart();
List<Song> dplist1 = null;
using (var conn = g.mysql.Ado.MasterPool.Get()) {
dplist1 = Dapper.SqlMapper.Query<Song>(conn.Value, "select * from song").ToList();
}
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper");
}
更多测试源码:FreeSql/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs