考虑以下 C# 代码:
IEnumerable numbers = Enumerable.Range(0, 10);
var evens = from num in numbers where num % 2 == 0 select num;
这是允许我将 for 或 foreach 循环编写为单行代码的纯语法糖吗?是否有任何编译器优化可以使上面的列表理解比循环构造更有效?这是如何工作的?
最佳答案
正如 Jason 所说,您的代码等同于:
Enumerable.Range(0, 10).Where(n => n % 2 == 0);
请注意,lambda 将转换为对每个元素执行的函数调用。这可能是开销的最大部分。我做了一个测试,表明 LINQ 在这个确切的任务上慢了大约 3 倍(mono gmcs 版本 1.2.6.0)
Time for 10000000 for loop reps: 00:00:17.6852560
Time for 10000000 LINQ reps: 00:00:59.0574430
Time for 1000000 for loop reps: 00:00:01.7671640
Time for 1000000 LINQ reps: 00:00:05.8868350
EDIT: Gishu reports that VS2008 and framework v3.5 SP1 gives:
Time for 1000000 loop reps: :00.3724585
Time for 1000000 LINQ reps: :00.5119530
LINQ is about 1.4 times slower there.
It compares a for-loop and a list to LINQ (and whatever structure it uses internally). Either way, it converts the result to an array (necessary to force LINQ to stop being "lazy"). Both versions repeat:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
public class Evens
{
private static readonly int[] numbers = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
private static int MAX_REPS = 1000000;
public static void Main()
{
Stopwatch watch = new Stopwatch();
watch.Start();
for(int reps = 0; reps < MAX_REPS; reps++)
{
List<int> list = new List<int>(); // This could be optimized with a default size, but we'll skip that.
for(int i = 0; i < numbers.Length; i++)
{
int number = numbers[i];
if(number % 2 == 0)
list.Add(number);
}
int[] evensArray = list.ToArray();
}
watch.Stop();
Console.WriteLine("Time for {0} for loop reps: {1}", MAX_REPS, watch.Elapsed);
watch.Reset();
watch.Start();
for(int reps = 0; reps < MAX_REPS; reps++)
{
var evens = from num in numbers where num % 2 == 0 select num;
int[] evensArray = evens.ToArray();
}
watch.Stop();
Console.WriteLine("Time for {0} LINQ reps: {1}", MAX_REPS, watch.Elapsed);
}
}
过去对类似任务的性能测试(例如 LINQ vs Loop - A performance test)证实了这一点。
关于C# 列表解析 = 纯语法糖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/954112/
我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some