我正在开发一个C#应用程序,它允许用户基本上导入数据表,然后用迷你语言输入他们自己的公式,从底层数据计算新列.
这些公式被编译到引擎中的LINQ表达式树中,然后.NET 4.0表达式树库可能会编译成IL,因此可以执行它们.
我们最近开始使用我们的引擎获取一些高容量的滴答数据,我们发现这些编译的表达式树的速度是一个真正的瓶颈 - 在动态重新计算所有这些列时速度相当慢.使用内置的Visual Studio 2010探查器进行攻击,可以看出我们所有执行时间的一半都花在了clr.dll中,这个方法名为JIT_MethodAccessAllowedBySecurity.
粗略的谷歌搜索这个字符串并没有产生任何东西,所以我想知道是否有人可以告诉我这个方法是什么,以及是否有办法让它不吃掉我所有的周期?也许有一种方法可以编译这段代码并明确授予它做任何想做的事情,这样clr可以停止这些检查吗?也许表达式树引擎生成的临时程序集没有完全信任?
无论如何,我几乎不知所措,我很想知道其他任何StackOverflow'ers过去是否遇到过这个问题.提前致谢!
我有一个用C#编写的接口,定义如下:
public interface IWidget
{
object Evaluate();
event EventHandler Invalidated;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试在F#中实现这个接口时,我会看看F#认为IWidget接口是什么(通过将鼠标悬停在它上面),我看到了
type IWidget =
interface
member Evaluate : unit -> obj
end
Run Code Online (Sandbox Code Playgroud)
它似乎完全忽略了Invalidated事件......这是F#的一个已知问题,如果有的话有什么方法可以解决它吗?在实现我的F#版本的IWidget时,我可以在IWidget部分之外实现此事件或者什么?f#处理"event"关键字这么糟糕......这似乎真的很讨厌......
更新:在进一步摆弄后,工作室然后说:
'没有给出IWidget.remove_Invalidate(value:EventHandler)的实现:unit'
然后,当我添加这些方法时,整个事情看起来像:
interface IWidget with
member w.Evaluate() = new obj()
member w.add_Invalidated(value:EventHandler) = ()
member w.remove_Invalidated(value:EventHandler) = ()
end
Run Code Online (Sandbox Code Playgroud)
它编译得很好,即使工具提示仍然说IWidget的唯一成员是Evaluate()......似乎F#(或至少IDE)处理这些东西的方式真的很棘手......
另一个更新:根据IDE中的工具提示,[]标签允许将事件编译为CLI元数据事件,方法是将其转换为一对add_/remove_方法......对于任何被困惑的人来说都是FYI就像我一样.简而言之,要么实现这两个方法,要么使用该标记工作正常,尽管IWdiget接口的工具提示视图没有提到Invalidate事件,并且只有在编译器抛出时才会注意到实现这样的事件的必要性.错误,仍然是一个明显的错误,并且非常令人困惑.对于任何好奇的人,以下代码工作正常:
let invalidated = new DelegateEvent<System.EventHandler>()
interface IWidget with
member w.Evaluate() = new obj()
[<CLIEvent>]
member w.Invalidated = invalidated.Publish
end
Run Code Online (Sandbox Code Playgroud)
谢谢各位的帮助!
我有点不好意思承认这一点,但我似乎对应该是一个简单的编程问题感到非常难过.我正在构建一个决策树实现,并且一直使用递归来获取标记样本列表,递归地将列表拆分为一半,然后将其转换为树.
不幸的是,对于深树,我遇到堆栈溢出错误(哈!),所以我的第一个想法是使用continuation将其转换为尾递归.不幸的是,Scala不支持这种TCO,因此唯一的解决方案是使用蹦床.蹦床似乎效率低下,我希望有一些简单的基于堆栈的必要解决方案来解决这个问题,但我找到它时遇到了很多麻烦.
递归版本看起来有点像(简化):
private def trainTree(samples: Seq[Sample], usedFeatures: Set[Int]): DTree = {
if (shouldStop(samples)) {
DTLeaf(makeProportions(samples))
} else {
val featureIdx = getSplittingFeature(samples, usedFeatures)
val (statsWithFeature, statsWithoutFeature) = samples.partition(hasFeature(featureIdx, _))
DTBranch(
trainTree(statsWithFeature, usedFeatures + featureIdx),
trainTree(statsWithoutFeature, usedFeatures + featureIdx),
featureIdx)
}
}
Run Code Online (Sandbox Code Playgroud)
所以基本上我根据数据的某些特性递归地将列表细分为两个,并通过一系列已使用的功能,所以我不再重复 - 这些都是在"getSplittingFeature"函数中处理的,所以我们可以忽略它.代码非常简单!尽管如此,我仍然难以找到一个基于堆栈的解决方案,它不仅仅使用闭包而且有效地变成了蹦床.我知道我们至少要在堆栈中保留少量"参数"框架,但我想避免关闭调用.
我知道我应该在递归解决方案中明确地写出callstack和程序计数器为我处理的内容,但是如果没有continuation,我就很难做到这一点.在这一点上,它几乎没有效率,我只是好奇.所以,请不要提醒我,过早优化是所有邪恶的根源,基于蹦床的解决方案可能会正常工作.我知道它可能会 - 这基本上是一个谜题,它本身就是为了它.
任何人都可以告诉我这种规范的基于循环和堆栈的规范解决方案是什么?
更新:基于Thipor Kong的优秀解决方案,我编写了一个基于while循环/堆栈/哈希表的算法实现,它应该是递归版本的直接转换.这正是我所寻找的:
最终更新:我使用了顺序整数索引,并将所有内容放回到数组而不是地图中以获得性能,添加了maxDepth支持,最后得到的解决方案具有与递归版本相同的性能(不确定内存使用情况但是我会猜的更少):
private def trainTreeNoMaxDepth(startingSamples: Seq[Sample], startingMaxDepth: Int): DTree = {
// Use arraybuffer as dense mutable int-indexed map - no IndexOutOfBoundsException, just expand to fit
type DenseIntMap[T] = ArrayBuffer[T] …Run Code Online (Sandbox Code Playgroud) 我使用Google Docs .NET API编写了一个C#程序,根据用户名,密码,电子表格名称和工作表名称将Google工作表读入DataTable.这一切都运行正常,但编程模型似乎围绕为电子表格服务提供一组凭据,然后削减结果Feed以获取特定的电子表格/工作表,即
SpreadsheetsService service = new SpreadsheetsService("Application-Name");
service.setUserCredentials(userName, password);
SpreadsheetQuery spreadsheetQuery = new SpreadsheetQuery();
SpreadsheetFeed spreadsheetFeed = service.Query(spreadsheetQuery);
SpreadsheetEntry spreadsheetEntry = (SpreadsheetEntry)(from entries in spreadsheetFeed.Entries
where entries.Title.Text == spreadsheetName
select entries).SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)
现在,我有兴趣扩展我的程序功能,以便从公共Google电子表格中读取.也就是说,考虑到公开Google电子表格的网址(例如" https://spreadsheets.google.com/ccc?key=BUNCH_OF_LETTERS_HERE&hl=en "),我想获取与该文档相对应的SpreadsheetEntry对象.
到目前为止我一直使用的方法显然似乎没有扩展到允许这个,所以我想知道是否有人知道通过他们的API访问公共Google文档的正确方法?
我在Scala中为构造函数注入创建了一个简单的依赖注入框架.这个想法是DI'd的对象将它们所需的服务放在它们的构造函数中,就像常规参数一样,并实现一个类型类,确定它们从容器中取出哪些参数,以及用户在实例化时传递哪些参数.
所以,它应该看起来像:
trait Container {
private singletons: Map[Class, AnyRef]
def getSingleton[T: Manifest] =
singletons(implicitly[Manifest[T]].erasure).asInstanceOf[T]
... methods for adding singletons, etc ...
}
class Foo(arg: String, svc: FooService) {
...
}
trait Constructor[T] { ??? }
object FooConstructor extends Constructor[Foo] {
def construct(arg: String)(implicit container: Container) =
new Foo(arg, container.getSingleton[FooService])
}
Run Code Online (Sandbox Code Playgroud)
现在基本上我希望能够有一个叫方法construct,我可以打电话的construct[Foo]("asd"),并得到一个新的实例Foo与"asd"传递给构造函数,并FooService得到了来自当地的容器中,传递给构造函数.这个想法是它应该以类型安全的方式获取Constructor类型类的实例Foo,知道它应该具有的参数的数量和类型.此外,这是困难的部分,我不想写出参数的类型 - 只是要构造的对象.
我尝试了几件事:
trait Constructor1[T, A] {
def construct(arg: A): T
}
trait Constructor2[T, A1, …Run Code Online (Sandbox Code Playgroud)