作者:梁利锋 标签:DotNet, DbEntry

4189天前 (阅读:6914)
  最近在网上看到有一个 ORM 作者称,因为从反射改为 Emit,所以,新版本比旧版本速度快了 90 倍,虽然心里不以为然,却还是忍不住想:反射真的有那么慢么?

  于是用 DbEntry v0.31 做了一个实验,来测试一下速度。

  程序很直白,都是使用 DbEntry 连接数据库,不过使用不同的方法,连接的数据库是 SQL Server 2005 Express,数据是我在分页例子程序中提供的数据,一共一万项。因为基本都是字符串类型的字段,可能不太具有代表性,不过,这个程序也只是要给出一个大体的比例而已,所以还好。

  程序代码如下,所有测试都运行了两次,第一次是为了让它先做一下预读:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using org.hanzify.llf.Data;
using org.hanzify.llf.Data.Definition;
using org.hanzify.llf.Data.SqlEntry;
using org.hanzify.llf.util;

public class TestTable
{
  [DbKey] public int id;
  public string UserName;
  public string EMail;
  public string HomePage;
}

class Program
{
  static void Main(string[] args)
  {
    RunAdoNetWithIndex();
    RunAdoNetWithIndex();
    RunAdoNetWithName();
    RunAdoNetWithName();
    RunAdoNetWithNameDontInsertToList();
    RunAdoNetWithNameDontInsertToList();
    RunDbEntry();
    RunDbEntry();
    RunDbEntryWithSQL();
    RunDbEntryWithSQL();
    RunDataSet();
    RunDataSet();

    Console.WriteLine("All end.");
    Console.ReadLine();
  }

  static void RunAdoNetWithIndex()
  {
    Console.WriteLine("Run ADO.NET with index:");
    TimeSpanCounter tc = new TimeSpanCounter();

    SqlStatement sql = new SqlStatement("select [id],[UserName],EMail,[HomePage] from [TestTable]");
    List<TestTable> l = new List<TestTable>();
    DbEntry.Context.ExecuteDataReader(sql, delegate(IDataReader dr)
    {
      while (dr.Read())
      {
        TestTable t = new TestTable();
        t.id = (int)dr[0];
        t.UserName = (string)dr[1];
        t.EMail = (string)dr[2];
        t.HomePage = (string)dr[3];
        l.Add(t);
      }
    });

    Console.WriteLine(tc);
    Console.WriteLine();
  }

  static void RunAdoNetWithName()
  {
    Console.WriteLine("Run ADO.NET with name:");
    TimeSpanCounter tc = new TimeSpanCounter();

    SqlStatement sql = new SqlStatement("select [id],[UserName],EMail,[HomePage] from [TestTable]");
    List<TestTable> l = new List<TestTable>();
    DbEntry.Context.ExecuteDataReader(sql, delegate(IDataReader dr)
    {
      while (dr.Read())
      {
        TestTable t = new TestTable();
        t.id = (int)dr["id"];
        t.UserName = (string)dr["UserName"];
        t.EMail = (string)dr["EMail"];
        t.HomePage = (string)dr["HomePage"];
        l.Add(t);
      }
    });

    Console.WriteLine(tc);
    Console.WriteLine();
  }

  static void RunAdoNetWithNameDontInsertToList()
  {
    Console.WriteLine("Run ADO.NET with name don't insert to list:");
    TimeSpanCounter tc = new TimeSpanCounter();

    SqlStatement sql = new SqlStatement("select [id],[UserName],EMail,[HomePage] from [TestTable]");
    DbEntry.Context.ExecuteDataReader(sql, delegate(IDataReader dr)
    {
      while (dr.Read())
      {
        TestTable t = new TestTable();
        t.id = (int)dr["id"];
        t.UserName = (string)dr["UserName"];
        t.EMail = (string)dr["EMail"];
        t.HomePage = (string)dr["HomePage"];
      }
    });

    Console.WriteLine(tc);
    Console.WriteLine();
  }

  static void RunDbEntry()
  {
    Console.WriteLine("Run DbEntry:");
    TimeSpanCounter tc = new TimeSpanCounter();

    List<TestTable> l = DbEntry.From<TestTable>().Where(null).Select();

    Console.WriteLine(tc);
    Console.WriteLine();
  }

  static void RunDbEntryWithSQL()
  {
    Console.WriteLine("Run DbEntry with SQL:");
    TimeSpanCounter tc = new TimeSpanCounter();

    List<TestTable> l = DbEntry.Context.ExecuteList<TestTable>("select [id],[UserName],EMail,[HomePage] from [TestTable]");

    Console.WriteLine(tc);
    Console.WriteLine();
  }

  static void RunDataSet()
  {
    Console.WriteLine("Run DataSet:");
    TimeSpanCounter tc = new TimeSpanCounter();

    DataSet ds = DbEntry.Context.ExecuteDataset("select [id],[UserName],EMail,[HomePage] from [TestTable]");

    Console.WriteLine(tc);
    Console.WriteLine();
  }
}


  其中一次运行结果如下:

Run ADO.NET with index:
Time span is 190.2736 ms.

Run ADO.NET with index:
Time span is 50.072 ms.

Run ADO.NET with name:
Time span is 60.0864 ms.

Run ADO.NET with name:
Time span is 80.1152 ms.

Run ADO.NET with name don't insert to list:
Time span is 60.0864 ms.

Run ADO.NET with name don't insert to list:
Time span is 50.072 ms.

Run DbEntry:
Time span is 210.3024 ms.

Run DbEntry:
Time span is 120.1728 ms.

Run DbEntry with SQL:
Time span is 170.2448 ms.

Run DbEntry with SQL:
Time span is 130.1872 ms.

Run DataSet:
Time span is 110.1584 ms.

Run DataSet:
Time span is 80.1152 ms.

All end.


  从中可以看出,确实直接使用 ADO.NET 的 DataReader 会快一些,不过,这是肯定的,因为底层都是使用的 DataReader,但是绝对不会到 90 倍那么夸张。另外,以前就听说 .Net 2.0 中 DataSet 做了优化,速度快了不少,在这次测试中确实表现还是不错的。至于 DbEntry ORM,虽然是最慢的,倒也没有差很多,不过总的来说,还是有进步的空间 :)

都督府(非注册用户) 2010-1-5 19:11:15

有了DbEntry是不是DAL层可以不要了?

梁利锋 2010-1-5 21:46:50

@都督府
基本上可以这么说。

Weeeee, what a quick and easy slotuion.(非注册用户) 2012-10-24 19:31:36

Weeeee, what a quick and easy slotuion.

Ah, i see. Well th'ats not too tricky at all!"(非注册用户) 2015-1-20 0:37:42

Ah, i see. Well th'ats not too tricky at all!"