我最近开始使用LINQ了,我还没有真正看到任何LINQ方法的运行时复杂性.显然,这里有很多因素在起作用,所以让我们将讨论局限于普通的IEnumerable
LINQ-to-Objects提供者.此外,假设任何Func
作为选择器/ mutator /等传入的是廉价的O(1)操作.
它似乎很明显,所有的单次操作(Select
,Where
,Count
,Take/Skip
,Any/All
,等)将是O(n)的,因为他们只需要步行的顺序一次; 虽然这甚至会受到懒惰的影响.
对于更复杂的操作来说,事情变得更加模糊; 集合类运算符(Union
,Distinct
,Except
等)使用工作GetHashCode
在默认情况下(据我所知),所以它似乎是合理的假设他们使用一个哈希表内,使这些操作为O(n)为好,一般.使用的版本怎么样IEqualityComparer
?
OrderBy
需要排序,所以很可能我们正在看O(n log n).如果它已经排序了怎么办?如果我说OrderBy().ThenBy()
并为两者提供相同的密钥怎么样?
我可以看到GroupBy
(和Join
)使用排序或散列.这是什么?
Contains
将是O(n)on a List
,但是O(1)on a HashSet
- LINQ检查底层容器以查看它是否可以加快速度?
真正的问题 - 到目前为止,我一直坚信运营是高效的.但是,我可以依靠吗?例如,STL容器清楚地指定了每个操作的复杂性..NET库规范中的LINQ性能是否有类似的保证?
更多问题(回应评论):
没有真正想过开销,但我没想到对于简单的Linq-to-Objects有很多.CodingHorror帖子讨论的是Linq-to-SQL,在那里我可以理解解析查询并使SQL增加成本 - 对象提供者也有类似的成本吗?如果是这样,如果您使用声明性或功能性语法,它会有所不同吗?
我正在尝试从C++和Java中的文件读取/写入多个Protocol Buffers消息.谷歌建议在消息之前写长度前缀,但默认情况下没办法(我可以看到).
但是,2.1.0版中的Java API收到了一组"Delimited"I/O函数,显然可以完成这项工作:
parseDelimitedFrom
mergeDelimitedFrom
writeDelimitedTo
Run Code Online (Sandbox Code Playgroud)
有C++等价物吗?如果没有,那么Java API附加的大小前缀是什么,所以我可以用C++解析这些消息?
这些现在存在于google/protobuf/util/delimited_message_util.h
v3.3.0中.
我听说任务并行库可以在.Net 3.5项目中使用.这是否正确,如果是,我该如何使用它?在.Net 4.0中,它驻留在System.Threading中,但是当我在Visual Studio 2010中选择.Net 3.5作为目标时,我无法访问Parallel和Parallel循环等类.
如何使用我自己的命令行名称运行python脚本,如'myscript'而不必在终端中执行'python myscript.py'?
def logical_xor(a, b): # for example, -1 and 1
print (a < 0) # evaluates to True
print (b < 0) # evaluates to False
print (a < 0 != b < 0) # EVALUATES TO FALSE! why??? it's True != False
return (a < 0 != b < 0) # returns False when it should return True
print ( logical_xor(-1, 1) ) # returns FALSE!
# now for clarification
print ( True != False) # PRINTS TRUE!
Run Code Online (Sandbox Code Playgroud)
有人可以解释发生了什么吗?我想做一个班轮:
lambda …
Run Code Online (Sandbox Code Playgroud) ParallelEnumerable
有一个静态成员AsParallel
.如果我有一个IEnumerable<T>
并且想要使用Parallel.ForEach
那意味着我应该一直使用AsParallel
吗?
例如,这些都是正确的(其他一切都是平等的)吗?
没有AsParallel
:
List<string> list = new List<string>();
Parallel.ForEach<string>(GetFileList().Where(file => reader.Match(file)), f => list.Add(f));
Run Code Online (Sandbox Code Playgroud)
还是用AsParallel
?
List<string> list = new List<string>();
Parallel.ForEach<string>(GetFileList().Where(file => reader.Match(file)).AsParallel(), f => list.Add(f));
Run Code Online (Sandbox Code Playgroud) edit4:wikified ,因为这似乎已经变成了讨论而不是特定的问题.
在C++编程中,通常认为"更喜欢非成员非朋友函数"而不是实例方法是一种好习惯.这是Scott Meyers在这篇经典的Dr. Dobbs文章中推荐的,Herb Sutter和Andrei Alexandrescu在C++编码标准中重复了这一点(第44项); 一般的论点是,如果一个函数只能通过依赖类暴露的公共接口来完成它的工作,它实际上增加了封装,使其成为外部的.虽然这在某种程度上混淆了班级的"包装",但通常认为其好处是值得的.
现在,自从我开始用C#编程以来,我有一种感觉,这就是他们试图通过"非成员,非朋友的函数来实现这个概念的最终表达"接口".C#为混合添加了两个关键组件 - 第一个是接口,第二个是扩展方法:
因此,您可以通过会员的便利获得"非会员,非朋友"功能的封装优势.对我来说似乎是两全其美的事情; .NET库本身在LINQ中提供了一个光辉的例子.然而,我看到的每个地方都看到人们警告不要过度使用扩展方法; 甚至MSDN页面本身都说明:
通常,我们建议您谨慎实施扩展方法,并且只在必要时才实施.
(编辑:即使在目前的.NET库,我能看到它会一直有扩展,而不是实例方法有用的地方-例如,所有的实用功能List<T>
(Sort
,BinarySearch
,FindIndex
等)将是非常有用的如果他们被提升到IList<T>
- 获得这样的免费奖励功能可以为实现界面带来更多好处.)
那么判决是什么?扩展方法是封装和代码重用的极致,还是我只是在欺骗自己?
(编辑2 :对Tomas的回应 - 虽然C#确实从Java(过度,imo)OO心态开始,但似乎每个新版本都采用了更多的多范式编程;这个问题的主旨是使用扩展方法来推动风格改变(朝向更通用/功能性的C#)是有用或有价值的.)
到目前为止,使用此方法确定的唯一真正问题是,如果需要,您无法专门使用扩展方法.我一直在考虑这个问题,我想我已经找到了解决方案.
假设我有一个接口MyInterface
,我想扩展 -
我在MyExtension
静态类中定义我的扩展方法,并将其与另一个接口配对,调用它MyExtensionOverrider
.MyExtension
方法是根据这种模式定义的:
public static int MyMethod(this MyInterface obj, …
Run Code Online (Sandbox Code Playgroud) 我需要迭代树/图并产生一定的输出,但遵循一些规则:
_ d
/ / \
b c _e
/ / |
a f g
Run Code Online (Sandbox Code Playgroud)
预期的输出应该是(顺序不相关):
{'bde', 'bcde', 'abde', 'abcde', 'bdfe', 'bdfge', 'abdfe', ...}
Run Code Online (Sandbox Code Playgroud)
规则是:
我需要找到遵循这些规则的所有路径.不幸的是,我没有CS背景,我的脑袋正在爆炸.任何提示都会有所帮助.
编辑:这个结构非常接近我的树:
class N():
"""Node"""
def __init__(self, name, lefts, rights):
self.name = name
self.lefts = lefts
self.rights = rights
tree = N('d', [N('b', [N('a', [], [])], []), N('c', [], [])],
[N('e', [N('f', [], []), N('g', [], [])],
[])])
Run Code Online (Sandbox Code Playgroud)
或者可能更具可读性:
N('d', lefts =[N('b', lefts=[N('a', [], [])], rights=[]), N('c', [], …
Run Code Online (Sandbox Code Playgroud) 我想使用以下代码在字符串中查找以特定字母开头的单词。特定字母将由用户在文本框中提供。
这就是我所拥有的:
<!DOCTYPE html>
<html>
<body>
<input id="srch" type="text" />
<button onClick=searchword()>Search</button>
<p id="wrd" > hallo, this is a test john doe .
Another tea house pole.
</p>
</body>
<script>
function searchword() {
var s = document.getElementById("wrd").innerHTML;
var p= document.getElementById("srch").value;
var regx = new RegExp("(?:^|\W)" + p + "(\w+)(?!\w)","gi");
var re = regx, match, matches = [];
while (match = re.exec(s)) {
matches.push(match[0]);
}
alert(matches);
}
</script>
</html>
Run Code Online (Sandbox Code Playgroud) 我是Java的新手.在编写Map <>时,我发现声明Map<int, int>
是语法错误,而且没问题Map<Integer, Integer>
.是否只能在Java中实例化对象类型的泛型,而不是原语?如果是这样,基元的装箱/拆箱会有明显的性能损失吗?