这里我有一个简单的例子来查找字符串列表中的项目.通常我使用for循环或匿名委托来这样做:
int GetItemIndex(string search)
{
int found = -1;
if ( _list != null )
{
foreach (string item in _list) // _list is an instance of List<string>
{
found++;
if ( string.Equals(search, item) )
{
break;
}
}
/* use anonymous delegate
string foundItem = _list.Find( delegate(string item) {
found++;
return string.Equals(search, item);
});
*/
}
return found;
}
Run Code Online (Sandbox Code Playgroud)
LINQ对我来说是新的.我很好奇我是否可以使用LINQ来查找列表中的项目?怎么可能?
我有人被告知,因为.net linq是如此之慢,我们不应该使用它,并且想知道其他人是否得出了相同的结论,例如:
花了1443ms做了1000000000比较非LINQ.
花了4944ms与LINQ做了1000000000比较.
(慢243%)
非LINQ代码:
for (int i = 0; i < 10000; i++)
{
foreach (MyLinqTestClass1 item in lst1) //100000 items in the list
{
if (item.Name == "9999")
{
isInGroup = true;
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
花了1443ms做了1000000000比较非LINQ.
LINQ代码:
for (int i = 0; i < 10000; i++)
isInGroup = lst1.Cast<MyLinqTestClass1>().Any(item => item.Name == "9999");
Run Code Online (Sandbox Code Playgroud)
花了4944ms与LINQ做了1000000000比较.
我想它可以优化LINQ代码,但想到的是它很容易得到非常慢的LINQ代码,并且考虑到它不应该被使用.鉴于LINQ很慢,那么PLINQ也会很慢,NHibernate LINQ会很慢,所以不应该使用LINQ语句中的任何类型.
有没有人发现LINQ是如此之慢以至于他们希望从未使用它,或者我是否根据这样的基准做出了过于笼统的结论?
是IEnumerable<T>轻量级还是重量级的简单LINQ查询?它们如何与手写for或foreach循环比较?何时更喜欢LINQ与手动搜索有一般指导原则?
例如:
var lowNums =
from n in numbers
where n < 5
select n;
Run Code Online (Sandbox Code Playgroud)
相比:
List<int> lowNums = new List<int>();
foreach (int n in numbers)
{
if (n < 5)
{
lowNums.Add(n);
}
}
Run Code Online (Sandbox Code Playgroud)
我和一位同事谈论LINQ,他对使用它表示了一些犹豫.他猜测为了支持LINQ可以做的一切,可能会在"幕后"进行大量工作.
以上示例之间是否存在显着的性能差异?是否有任何好的资源可以谈论集合上的LINQ性能?一个简单的Google搜索linq表现出现了一些看似过时的文章.
下面是两个返回相同数据的查询.除了风格,我不确定哪个更好.
哪些因素会影响这些查询?使用一种风格而不是另一种风格有什么好处?
样品1
var x = from s in db.Surveys
join sq in db.Survey_Questions on s.ID equals sq.Survey_ID
join q in db.Questions on sq.Question_ID equals q.ID
join qg in db.Question_Groups on q.ID equals qg.Question_ID
where s.Type_ID.Equals(typeID) & s.Type.Equals(type)
select new { question = sq.Question, status = sq.Status, grp = qg };
Run Code Online (Sandbox Code Playgroud)
样本2
var x = db.Surveys.Where(s => s.Type_ID.Equals(typeID) & s.Type.Equals(type))
.Join(db.Survey_Questions,
s => s.ID,
sq => sq.Survey_ID,
(s, sq) => new
{
question = sq.Question,
status = sq.Status
})
.Join(db.Question_Groups, …Run Code Online (Sandbox Code Playgroud) 我写了这个字符串扩展一段时间后,我实际上得到了相当多的使用.
public static string Slice(this string str, int? start = null, int? end = null, int step = 1)
{
if (step == 0) throw new ArgumentException("Step cannot be zero.", "step");
if (start == null)
{
if (step > 0) start = 0;
else start = str.Length - 1;
}
else if (start < 0)
{
if (start < -str.Length) start = 0;
else start += str.Length;
}
else if (start > str.Length) start = str.Length;
if (end == null) …Run Code Online (Sandbox Code Playgroud) 我使用EF 4和C#.
我需要使用属于两个不同实体的两个属性来订购此查询的结果.
在我的情况下,我想订购gt.GroupTypeId和它subset by cnt.ContentId.
PS:我不确定我的头衔是否合适,如果你不认为,请告诉我,我会改变它:-)
from cnt in context.CmsContents
from gt in cnt.CmsGroupsTypes
join t in context.CmsTypes
on cnt.TypeContent equals t.TypeContent
join m in context.CmsModes
on cnt.ModeContent equals m.ModeContent
orderby gt.GroupTypeId // Problem here
select new
{
cnt.ContentId,
cnt.Title,
gt.TypeGroup,
gt.GroupTypeId,
TypeContentDescription = t.Description,
ModeContentDescription = m.Description,
cnt.IsPublished
};
Run Code Online (Sandbox Code Playgroud) 将类转换为另一个类列表的问题和答案很酷.如何将MyData列表转换为另一个MyData2列表?例如:
List<MyData> list1 = new List<MyData>();
// somewhere list1 is populated
List<MyData2> list2;
// Now I need list2 from list1. How to use similar LINQ or Lambda to get
list2 = ... ?
Run Code Online (Sandbox Code Playgroud)
在这里我尝试了这个,但我无法弄清楚完整的代码:
list2 = (from x in list1 where list1.PropertyList == null
select new MyData2( null, x.PropertyB, x.PropertyC).
Union (
from y in list1 where list.PropertyList != null
select new MyData2( /* ? how to loop each item in ProperyList */
y.PropertyB, y.PropertyC)
).ToList();
Run Code Online (Sandbox Code Playgroud)
其中MyData2有一个CTOR(字符串,字符串,字符串).
我做了一个小实验来测试lamdba表达式是否可以检索比foreach语句更快的结果.但是,Lambda失败了
System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
st.Start();
List<int> lst = new List<int>();
foreach (GridViewRow item in GridView1.Rows)
{
if (((CheckBox)item.FindControl("Check")).Checked)
{
lst.Add(Convert.ToInt32(((Label)item.FindControl("Id")).Text));
}
}
st.Stop();
Response.Write(st.Elapsed.ToString());
Response.Write("<br/><br/><br/>");
st.Reset();
st.Start();
List<int> lstRank = GridView1.Rows.OfType<GridViewRow>().Where(s => ((CheckBox)s.FindControl("Check")).Checked)
.Select(s => Convert.ToInt32(((Label)s.FindControl("Id")).Text)).ToList();
st.Stop();
Response.Write(st.Elapsed.ToString());
int i = 0;
output
00:00:00.0000249
00:00:00.0002464
Run Code Online (Sandbox Code Playgroud)
为什么lambda比foreach慢.这可能是lambda表达式的缺点