public async Task Test_EntityMapperPerformanceAsync(int index) { index++; IDatabase database = _sqlite; IList <BookEntity_Client>?books = Mocker.GetBooks_Client(500); TransactionContext?trans = await _sqlIteTransaction.BeginTransactionAsync <BookEntity_Client>().ConfigureAwait(false); IEnumerable <BookEntity_Client> re = await database.RetrieveAsync <BookEntity_Client>(b => b.Deleted, trans).ConfigureAwait(false); await database.AddAsync <BookEntity_Client>(Mocker.GetBooks_Client(1)[0], "", trans).ConfigureAwait(false); try { //await database.AddAsync<BookEntity>(books[0], "", trans); await database.BatchAddAsync(books, "x", trans).ConfigureAwait(false); await _sqlIteTransaction.CommitAsync(trans).ConfigureAwait(false); } catch { await _sqlIteTransaction.RollbackAsync(trans).ConfigureAwait(false); } Stopwatch stopwatch = new Stopwatch(); using SqliteConnection mySqlConnection = new SqliteConnection("Data Source=sqlite_test2.db"); //time = 0; int loop = 10; TimeSpan time0 = TimeSpan.Zero, time1 = TimeSpan.Zero, time2 = TimeSpan.Zero, time3 = TimeSpan.Zero; for (int cur = 0; cur < loop; ++cur) { await mySqlConnection.OpenAsync().ConfigureAwait(false); using SqliteCommand command0 = new SqliteCommand("select * from tb_bookentity_client limit 1000", mySqlConnection); SqliteDataReader?reader0 = await command0.ExecuteReaderAsync().ConfigureAwait(false); List <BookEntity_Client> list1 = new List <BookEntity_Client>(); List <BookEntity_Client> list2 = new List <BookEntity_Client>(); List <BookEntity_Client> list3 = new List <BookEntity_Client>(); int len = reader0.FieldCount; EntityPropertyDef[] propertyDefs = new EntityPropertyDef[len]; MethodInfo[] setMethods = new MethodInfo[len]; EntityDef definition = EntityDefFactory.GetDef <BookEntity_Client>() !; for (int i = 0; i < len; ++i) { propertyDefs[i] = definition.GetPropertyDef(reader0.GetName(i)) !; setMethods[i] = propertyDefs[i].SetMethod; } Func <IDataReader, object> mapper1 = EntityMapperDelegateCreator.CreateToEntityDelegate(definition, reader0, 0, definition.FieldCount, false, Database.Engine.EngineType.SQLite); //Warning: 如果用Dapper,小心DateTimeOffset的存储,会丢失offset,然后转回来时候,会加上当地时间的offset TypeHandlerHelper.AddTypeHandlerImpl(typeof(DateTimeOffset), new DateTimeOffsetTypeHandler(), false); Func <IDataReader, object> mapper2 = DataReaderTypeMapper.GetTypeDeserializerImpl(typeof(BookEntity_Client), reader0); Stopwatch stopwatch1 = new Stopwatch(); Stopwatch stopwatch2 = new Stopwatch(); Stopwatch stopwatch3 = new Stopwatch(); while (reader0.Read()) { stopwatch1.Start(); object obj1 = mapper1(reader0); list1.Add((BookEntity_Client)obj1); stopwatch1.Stop(); stopwatch2.Start(); object obj2 = mapper2(reader0); list2.Add((BookEntity_Client)obj2); stopwatch2.Stop(); stopwatch3.Start(); BookEntity_Client item = new BookEntity_Client(); for (int i = 0; i < len; ++i) { EntityPropertyDef property = propertyDefs[i]; object?value = TypeConvert.DbValueToTypeValue(reader0[i], property, Database.Engine.EngineType.SQLite); if (value != null) { setMethods[i].Invoke(item, new object?[] { value }); } } list3.Add(item); stopwatch3.Stop(); } time1 += stopwatch1.Elapsed; time2 += stopwatch2.Elapsed; time3 += stopwatch3.Elapsed; await reader0.DisposeAsync().ConfigureAwait(false); command0.Dispose(); await mySqlConnection.CloseAsync().ConfigureAwait(false); } _output.WriteLine("Emit Coding : " + (time1.TotalMilliseconds / (loop * 1.0)).ToString(CultureInfo.InvariantCulture)); _output.WriteLine("Dapper : " + (time2.TotalMilliseconds / (loop * 1.0)).ToString(CultureInfo.InvariantCulture)); _output.WriteLine("Reflection : " + (time3.TotalMilliseconds / (loop * 1.0)).ToString(CultureInfo.InvariantCulture)); }