- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
更新:事实证明反射也不一定很慢。使用 Fasterflect (http://www.codeproject.com/Articles/38840/Fasterflect-a-fast-and-simple-API-for-Reflection-i)。它从字面上进行反射(我指的是最字面意义上的“字面意思”一词,而不是比喻,因为它经常被误用)快了 100 倍。
我的代码现在已经达到加载数据并将数据放入我的业务对象的速度,就像 sql server management studio 在表上执行 select * 一样快。
我刚刚运行了这段代码来检查表中的任何数据类型并使用适当的 Get 方法:
foreach (var p in obj.Properties)
{
object value;
var i = fieldNumbers[p.Alias];
if (p.Type == "System.Nullable`1[System.Int16]") value = dr.GetSqlInt16(i);
else if (p.Type == "System.Nullable`1[System.Int32]") value = dr.GetSqlInt32(i);
else if (p.Type == "System.Nullable`1[System.Decimal]") value = dr.GetSqlDecimal(i);
else if (p.Type == "System.Nullable`1[System.Boolean]") value = dr.GetSqlBoolean(i);
else if (p.Type == "System.String") value = dr.GetSqlString(i);
else if (p.Type == "System.Nullable`1[System.DateTime]") value = dr.GetSqlDateTime(i);
}
还有这个:
foreach (var p in obj.Properties)
{
object value;
var i = fieldNumbers[p.Alias];
value = dr[i];
}
第二个始终执行得更快。我对此感到惊讶,但这似乎是真的。谁能告诉我是否忽略了这里的某些内容,因为我看到有几个人声称使用 GetXXX 方法性能更好。我将其作为一个整体进行计时,也对单独的检索操作进行计时。我真的只是揭穿了一个神话吗?
编辑:经过更多测试后,我发现了一些问题。
1st - 使用将值返回到强类型变量中的 get 方法稍微快一点(我运行的测试大约快 8%),我在没有上面所有多余代码的情况下测试了它,所以没有调度或类似的东西......只是苹果对苹果。
但是请注意,我使用的是 GetSqlXXX 函数而不是 GetXXX 函数。这是因为后者不能用于空值。但是,前者返回类型如 SqlInt32 而不是 int?。虽然我的字段不是 SqlXXX,但它们是简单的可空类型,如 int?。我认为大多数人经常会遇到这种情况,这意味着除非您想在整个代码中开始使用 SqlTypes,否则您不会真正获得类型化方法的速度提升。
其次,我注意到检索空值似乎比您通常预期的要慢......但这当然只是我的看法。
编辑 2:对于 Doug McClean 和 TheEvilPenguin,我“只是”分支的时间如下:
Stopwatch sw = new Stopwatch();
long time = 0;
while (dr.Read())
{
var obj = new O();
obj.Initializing = true;
sw.Restart();
foreach (var p in obj.Properties)
{
if (p.Type == "System.Nullable`1[System.Int16]") continue;
else if (p.Type == "System.Nullable`1[System.Int32]") continue;
else if (p.Type == "System.Nullable`1[System.Decimal]") continue;
else if (p.Type == "System.Nullable`1[System.Boolean]") continue;
else if (p.Type == "System.String") continue;
}
time += sw.ElapsedTicks;
}
sw.Stop();
MessageBox.Show(time.ToString());
我不得不在其中留下几行不特定于分支的行,但您可以看到我只是在分支周围添加时间。起初我以毫秒为单位完成,结果(大约 60k 条记录)为 1。显然每个周期小于一毫秒,所以我切换到滴答声,结果为 466472,小于 1 毫秒的一半(除非我得到我的小数位混淆了......如果我不在,请有人纠正我)。那么分支有多贵?不是。
实际上,这些结果看起来确实很小,所以如果我在测试中犯了错误,请有人纠正我,但无论哪种方式,分支都是您可以做的最便宜的事情之一。
最佳答案
这一切都取决于 ADO 提供程序,这个答案涉及 SQL Server ADO.NET 提供程序,又名 SqlClient
。
查看您的基准测试,它看起来无效。特别是您要将一堆字符串比较添加到组合中。
对于有效的微基准测试,GetXYZ
是 little 一点点,因为 GetValue
的开销稍微多一些,特别是:
GetValue
将内容汇集到内部 SqlBuffer.Value
中,这是一个简单的 case 语句,它分派(dispatch)给 GetXYZ
分派(dispatch)的相同属性.
GetValue
调用 SqlStatistics.StartTimer
而 GetXYZ
调用则不会。
您可能可以 IL bake 一个稍快的 GetValue()
实现,我怀疑这是否值得。
以下微基准测试展示了性能差异:
// include Dapper from nuget
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using Dapper;
using System.Diagnostics;
namespace ConsoleApplication16
{
class Program
{
static void Main(string[] args)
{
var cnn = new SqlConnection("Data Source=.;Initial Catalog=tempdb;Integrated Security=True");
cnn.Open();
cnn.Execute("create table #t(num int, str nvarchar(50))");
// 10 k records
cnn.Execute("insert #t values (@num, @str)",
Enumerable.Range(1, 10000).Select(i => new { num = i, str = Guid.NewGuid().ToString() }));
Stopwatch sw;
SqlCommand cmd = new SqlCommand("select * from #t");
cmd.Connection = cnn;
for (int i = 0; i < 10; i++)
{
sw = Stopwatch.StartNew();
using (var reader = cmd.ExecuteReader())
{
int num;
string str;
while (reader.Read())
{
num = reader.GetInt32(0);
str = reader.GetString(1);
}
}
Console.WriteLine("GetXYZ {0}", sw.ElapsedTicks);
sw = Stopwatch.StartNew();
using (var reader = cmd.ExecuteReader())
{
int num;
string str;
while (reader.Read())
{
num = (int)reader.GetValue(0);
str = (string)reader.GetValue(1);
}
}
Console.WriteLine("GetValue {0}", sw.ElapsedTicks);
}
Console.ReadKey();
}
}
}
结果:
GetXYZ 25094GetValue 27877GetXYZ 24226GetValue 25450...GetXYZ 24029GetValue 26571
GetValue
始终如此缓慢。在绝对最坏的情况下差 5%。
关于c# - 为什么人们说 SqlDataReader.GetXXX(i) 比 SqlDataReader[i] 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9221944/
我正在编写一个 JS 程序,我有一个条件可以根据输入进行一些算术运算。如果我遇到操作类型为“add”,我需要将两个值相加;如果我得到“times”作为我的运算符值,我需要相乘。 我尝试使用基本的 if
我正在编写一个仅作为查看器的应用程序 - 无需创建、无需编辑、无需保存。 显然,那么,不会有自动保存,但是还有什么其他东西可以从 autosavesInPlace 返回 YES 改变世界,从而对观看者
Azure 开始出现以下错误: Unsupported token. Unable to initialize the authorization context. 每当我尝试更改我的应用程序时,我都
当我编写 out.println() 时,Eclipse 提示 out 无法解析。 我导入了 java.io.* 和其他 servlet 包。 最佳答案 只是在黑暗中拍摄,我认为这就是您正在寻找的出路
Azure 开始出现以下错误: Unsupported token. Unable to initialize the authorization context. 每当我尝试更改我的应用程序时,我都
是否可以执行类似的操作来检查 radio 表单是否未选中: if !($(this).find("input:checked")) {} 正确的语法是什么? 最佳答案 试试这个: $(this).fi
我正在尝试从表中选择行,其中 date 列值等于澳大利亚悉尼的当前日期 (UTC+10h)。服务器位于悉尼,因此我想使用 SYSDATETIME()。这是我的查询: SELECT * FROM dat
我听说 JavaScript 实际上并不像其他语言那样“指向”内存中的值(或对象,因为在 JS 中一切都是对象)。相反,JS 变量引用内存中的其他值/对象。这是真的?指向和引用之间的语义区别是什么?
我的计算机科学类(class)有一项作业,其中要求读取包含多个测试分数的文件,并要求我对它们进行求和并求平均值。虽然求和和求平均值很容易,但我在读取文件时遇到问题。老师说用这个语法 Scanner s
Java 的 XML 解析器似乎认为我的 XML 文档在根元素之后的格式不正确。但我已经用几种工具验证了它,但他们都不同意。这可能是我的代码错误,而不是文档本身的错误。如果你们能给我提供任何帮助,我将
根据这份文件: http://www.stroustrup.com/terminology.pdf l 值具有同一性且不可移动。 公关值是可移动的,但没有身份。 x 值具有同一性并且是可移动的。 关于
这个问题在这里已经有了答案: What does "atomic" mean in programming? (7 个答案) 关闭 5 年前。 我正在阅读 MongoDB 的 documentati
在 PHP 和 MySQL 中有没有一种方法能够比较 2 个不同的数组(列表)变量并说出有多少项是相同的 例如, $array1 = "hello, bye, google, laptop, yes"
本文来自 Effective Java Programs that use the int enum pattern are brittle. Because int enums are compil
C++ 中有一些特性是类型安全的,而另一些则不是。 C++ 类型安全示例: char c = 'a'; int *p = &c; // this is not allowed (compiler
我有一个 CS 课的作业,它说要读取一个包含多个测试分数的文件,并要求我对它们求和并取平均值。虽然求和和平均很容易,但我在读取文件时遇到了问题。老师说要用这个语法 Scanner scores = n
嗯.. 有时,PyDev 会说“ Unresolved 导入错误”。 在我的环境中 Python2.6.6 Eclipse3.7 PyDev2.2.2 错误是。 > Unresolved import
我正在向服务器发送请求,服务器正在处理请求并做出响应。但是在我的应用程序中,我收到了: Error Domain=NSURLErrorDomain Code=-1017 "cannot parse r
在我最近的一次讨论中,有人告诉我这样说是不正确的,因为 Ajax 已经是 Javascript。 上下文: “我如何在网页中 blablababal,这样它就不必刷新页面” 我的回答: “使用 Jav
下午好。 我一直在尝试使用 ffmpeg 将 .mpeg 拆分为一系列 .jpeg 图像。请注意,这是指定 here 的逆问题,但我面临的问题与该线程的作者面临的问题不同。 具体来说,我已经在我的 f
我是一名优秀的程序员,十分优秀!