我一直在F#做一些计算密集型的工作.功能类似于Array.Parallel.map其使用.NET任务并行库加快了我的代码成倍的真的很最小的努力.
但是,由于内存问题,我重新编写了我的代码的一部分,以便可以在序列表达式中进行延迟评估(这意味着我必须存储并传递较少的信息).到了评价我用的时候:
// processor and memory intensive task, results are not stored
let calculations : seq<Calculation> = seq { ...yield one thing at a time... }
// extract results from calculations for summary data
PSeq.iter someFuncToExtractResults results
Run Code Online (Sandbox Code Playgroud)
代替:
// processor and memory intensive task, storing these results is an unnecessary task
let calculations : Calculation[] = ...do all the things...
// extract results from calculations for summary data
Array.Parallel.map someFuncToExtractResults calculations
Run Code Online (Sandbox Code Playgroud)
当使用任何Array.Parallel函数时,我可以清楚地看到我的计算机上的所有内核都启动(CPU使用率约为100%).但是,所需的额外内存意味着程序永远不会完成.
在运行程序时使用PSeq.iter版本,CPU使用率仅为8%(并且RAM使用率最低).
那么:PSeq版本运行得如此之慢有什么原因吗?是因为懒惰的评价?我错过了一些神奇的"平行"的东西吗?
谢谢,
其他资源,两者的源代码实现(它们似乎在.NET中使用不同的并行库):
https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/array.fs
https://github.com/fsharp/powerpack/blob/master/src/FSharp.PowerPack.Parallel.Seq/pseq.fs …
parallel-processing f# lazy-evaluation seq task-parallel-library
无论如何都要在Silverlight中停止自动DataContext继承?
我在代码中的父UserControl上设置了我的DataContext.因此,UserControl内的所有xaml绑定都尝试绑定到它们获取的新DataConext(通过自动DataContext继承).
UserControl的子元素的DataContext(实际上它们是子元素的子元素)是我需要在UserControl的代码中设置的...我不希望它们都是智能的,因为它们最终绑定到错误的数据宾语!:-)
这个问题与此类似: 在C++中限制对特定类的方法访问
但是,我的问题是C#.
重申:我有两个类,比如说Foo和Bar紧密耦合.Foo公开了一个我只想要Bar访问的方法.
我有点想知道我想要什么,但不知道如何实际做到这一点,或者知道是否存在更简单的方法.它将涉及使用某种依赖于(new StackFrame(1)).GetMethod().DeclaringType拒绝访问的属性.用法看起来像这样:
public class Foo {
[RestrictedUsage(Allow=typeof(Bar))]
public int SomeMethod()
{
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
我可能缺少相关的细节问题(我是新来的) - 我一定会在我去的时候更新它.
更新:
我应该提一下,Foo包装一个现有UIElement的我试图修改的行为.由于课程是密封的,因此很难正常修改.Bar是将值转换为正确值的类.Bar是非UI,并在我的应用程序中的其他地方使用.Foo不知道如何转换价值(它很复杂 - 这就是Bar为什么),这就是为什么我不能只包装基本方法.
Jon Skeet给出了我期待的答案 - 改变课程的布局(感谢他到目前为止),但我认为任何一个答案都不适用(好的答案只是不相关).
我已经在代码中犯了错误,引用了错误的属性......
所以我有一个非常经常地调用方法作为模式的一部分.它看起来像这样:
DoWork(new TimeSpan(0, 0, 2, 0));
Run Code Online (Sandbox Code Playgroud)
或者在代码的另一部分:
DoWork(new TimeSpan(0, 0, 6, 50));
Run Code Online (Sandbox Code Playgroud)
在每种情况下,参数都不会改变,我最近醒来并找出了为每次调用创建参数的性能问题.我的解决方案是:
// instance field
TimeSpan _cachedValue = new TimeSpan(0, 0, 2, 0);
// and when called,
DoWork(this._cachedValue)
Run Code Online (Sandbox Code Playgroud)
这一点都非常明显,我遇到的问题是将参数值存储在一个字段中...它的凌乱 - 在一个已经膨胀的类中(例如我在一个类中调用10个左右的do work方法)每个变种数千次 - 所以这十个额外的领域).
如果我可以做这样的事情,那会很酷:
DoWork([DoesNotChange()]new TimeSpan(0, 0, 2, 0));
Run Code Online (Sandbox Code Playgroud)
参数的这个理论属性表明,对于该特定调用,该值只需要计算一次,然后重复传递给方法.
这样的事情可能吗?或者我刚刚离开我的坚果?
干杯
编辑:
哇你们大家工作快,谢谢.至于我的问题,我上次应该学会不要过度简化 - 对不起.为了清楚起见,我将发布一个实际的代码段.此类用于Silverlight应用程序中的数据绑定.我正在使用PropertyChanged事件的强类型来实现可维护性:
internal class BasicDataClass : INotifyPropertyChanged
{
private readonly Expression<Func<double>> _propertySelector;
private double _someFieldA;
private double _someFieldB;
private double _someFieldC;
public BasicDataClass()
{
_propertySelector = () => SomeFieldC;
}
/// <summary>
/// This …Run Code Online (Sandbox Code Playgroud)