编辑:这不是重复,它不是对如何使用随机数生成器的天真误解的结果.谢谢.
我似乎在System.Random类生成的数字中发现了重复模式.我正在使用"主"Random实例为第二个"主"Random实例生成种子.此主要Random实例生成的值显示重复模式.特别是,产生的第3个数字是非常可预测的.
下面的程序演示了这个问题.请注意,每次循环使用不同的种子值.
using System;
class Program
{
static void Main(string[] args)
{
// repeat experiment with different master RNGs
for (int iMaster = 0; iMaster < 30; ++iMaster)
{
// create master RNG
var rngMaster = new Random(iMaster + OFFSET);
// obtain seed from master RNG
var seed = rngMaster.Next();
// create main RNG from seed
var rngMain = new Random(seed);
// print 3rd number generated by main RNG
var ignore0 = rngMain.Next(LIMIT);
var ignore1 = rngMain.Next(LIMIT);
var randomNumber …
Run Code Online (Sandbox Code Playgroud) 如果我有一个如下所示的通用Item类:
abstract class Item<T>
{
}
Run Code Online (Sandbox Code Playgroud)
和一个看起来像这样的项目容器:
class Container<TItem, T>
where TItem : Item<T>
{
}
Run Code Online (Sandbox Code Playgroud)
由于TItem依赖于T,是否可以简化Container的类型签名,使其只需要一个类型参数?我真正想要的是这样的:
class Container<TItem>
where TItem : Item // this doesn't actually work, because Item takes a type parameter
{
}
Run Code Online (Sandbox Code Playgroud)
所以我可以实例化如下:
class StringItem : Item<string>
{
}
var good = new Container<StringItem>();
var bad = new Container<StringItem, string>();
Run Code Online (Sandbox Code Playgroud)
当TItem是StringItem时,编译器应该能够推断T是字符串,对吧?我该如何实现这一目标?
所需用法:
class MyItem : Item<string>
{
}
Container<MyItem> container = GetContainer();
MyItem item = container.GetItem(0);
item.MyMethod();
Run Code Online (Sandbox Code Playgroud) 在具有16GB RAM的Windows Server 2008 x64上运行.NET应用程序.此应用程序需要获取和分析大量数据(大约64GB),并将其全部保存在内存中.
我期待看到的:流程大小扩展到16GB到64GB.Windows根据需要使用虚拟内存将额外数据分页到磁盘或从磁盘分页.这是经典的虚拟内存使用案例.
我实际看到的:进程大小仅限于物理内存量(16GB).应用程序将99.8%的时间花在垃圾收集器上.
为什么我们的应用程序无法使用虚拟内存?这是.NET垃圾收集器配置中的问题,还是Windows x64虚拟内存管理器本身的问题?我该怎么做才能让我们的应用程序使用虚拟内存而不仅限于物理内存?
谢谢.
- 布莱恩
更新:我写了一个非常小的程序,表现出相同的行为:
using System;
namespace GCTest
{
class Program
{
static void Main()
{
byte[][] arrays = new byte[100000000][];
for (int i = 0; i < arrays.Length; ++i)
{
arrays[i] = new byte[320];
if (i % 100000 == 0)
{
Console.WriteLine("{0} arrays allocated", i);
System.Threading.Thread.Sleep(100);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想尝试它,请确保为x64构建.您可能需要稍微修改常量以强调您的系统.我看到的行为是,当进程接近16GB的大小时,进程陷入困境.没有抛出错误消息或异常.性能监视器报告GC中的CPU时间百分比接近100%.
这不是不可接受的吗?虚拟内存系统在哪里?
纯函数式编程的一个承诺是它很好地并行化.我正在使用具有平庸结果的F#应用程序测试此声明.我的程序通过Array.Parallel并行运行大量的MiniMax搜索.MiniMax算法是纯粹的功能代码 - 没有共享状态,没有锁定,但是高度递归,在搜索树时会创建和销毁大量值.根本没有I/O--一切都在内存中.每个MiniMax搜索需要5-60秒,我在一个带有8个CPU内核的快速盒子上并行运行大约100个.遗憾的是,CPU利用率达到65%左右,通常在45-60%的范围内.
我使用Visual Studio Concurrency Visualizer分析了我的应用程序,发现它在大约40%的时间内被阻止.所有阻塞调用似乎都在.NET垃圾收集器或其他.NET内存管理例程中.有没有办法优化这种行为,而无需用C++等低级语言重写整个程序?很明显,问题在于我正在创建和销毁太多的对象,但这在惯用的F#代码中很难避免.也许我错过了同步问题的其他一些原因?
谢谢.
更新:我做了两个更改:禁用超线程并在我的配置文件中使用gcServer.这使我的测试用例的执行时间从32秒减少到13秒!CPU利用率也高得多.感谢所有提出建议的人.
.net parallel-processing f# multithreading memory-management
如果我定义这样的类型:
type Foo = Items of seq<int>
Run Code Online (Sandbox Code Playgroud)
我可以创建Foo
如下:
Items [1;2;3]
Run Code Online (Sandbox Code Playgroud)
但是,以下不起作用:
[1;2;3] |> Items
Run Code Online (Sandbox Code Playgroud)
错误消息是:
Type mismatch. Expecting a
int list -> 'a
but given a
seq<int> -> Foo
Run Code Online (Sandbox Code Playgroud)
编译器不应该能够转换int list
成一个seq<int>
?如果Items
构造函数是一个普通函数,我可以调用它:
let length ints = Seq.length ints
printfn "%A" (length [1;2;3])
printfn "%A" ([1;2;3] |> length)
Run Code Online (Sandbox Code Playgroud) 是否可以创建直接调用方法的表达式树?例如,请考虑以下方法:
public static int MyFunc(int a, int b)
{
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个表达式树,调用MyFunc参数a = 1和b = 2.实现这一目标的一种方法是反思:
var c1 = Expression.Constant(1);
var c2 = Expression.Constant(2);
var expr = Expression.Call(typeof(Program).GetMethod("MyFunc"), c1, c2);
Run Code Online (Sandbox Code Playgroud)
但是,这是不利的,因为反射很慢并且应该将编译时错误转换为运行时错误.
我可以使用以下方法:
Expression<Func<int, int, int>> lambda = (a, b) => MyFunc(a, b);
var expr = Expression.Invoke(lambda, c1, c2);
Run Code Online (Sandbox Code Playgroud)
但这仍然不是我想要的,因为它将方法包装在lambda表达式中而不是直接调用它.
一个好的解决方案可能基于委托,如下所示:
Func<int, int, int> del = Program.MyFunc;
var expr = Expression.Invoke(del, c1, c2);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不会编译因为del
是委托而不是表达.有没有办法从委托构建表达式?(注意,我在编译时知道委托的目标,所以我不需要这里描述的那种灵活性:表达式树和调用委托.)
非委托解决方案也可以,只要它尽可能直接调用目标方法.
更新:这也有效,但它仍然依赖于反射:
Func<int, int, int> del = Program.MyFunc;
var …
Run Code Online (Sandbox Code Playgroud) 在EAV系统中,我有一个如下所示的映射:
<class name="Record">
<map name="Values" table="RecordFieldValue">
<key column="RecordFK">
<index column="FieldFK">
<element column="Value">
</map>
</class>
Run Code Online (Sandbox Code Playgroud)
我想选择一些记录,按特定字段的每个记录的值排序.但请注意,并非所有记录实际上都具有该字段的值.在这种情况下,仍应提取记录并使用空值进行排序.
所需的SQL如下所示:
select rec.*, val.Value
from Record rec
left outer join RecordFieldValue val
on val.RecordFK = rec.PK and val.FieldFK = :field
order by val.Value
Run Code Online (Sandbox Code Playgroud)
经过大量挖掘后,我发现在HQL中修改左连接的"on"子句的正确方法是使用"with"关键字(参见https://nhibernate.jira.com/browse/NH-514) .所以我尝试了这个HQL:
from Record rec
left join rec.Values vals with index(vals) = :field
order by vals
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会产生以下错误:with子句表达式没有引用与子句相关联的from子句元素.所以我尝试了这个:
from Record rec
left join rec.Values vals with index(rec.Values) = :field
order by vals
Run Code Online (Sandbox Code Playgroud)
但是这产生了一个新的错误:with子句只能引用驱动表中的列.
有关如何使这项工作的任何想法?谢谢.
- 布莱恩
F#中的类级别和成员级别自标识符之间是否存在语义差异?例如,考虑这个类:
type MyClass2(dataIn) as self =
let data = dataIn
do
self.PrintMessage()
member this.Data = data
member this.PrintMessage() =
printfn "Creating MyClass2 with Data %d" this.Data
Run Code Online (Sandbox Code Playgroud)
与本课程相比:
type MyClass2(dataIn) as self =
let data = dataIn
do
self.PrintMessage()
member this.Data = data
member this.PrintMessage() =
printfn "Creating MyClass2 with Data %d" self.Data
Run Code Online (Sandbox Code Playgroud)
唯一的区别是PrintMessage的实现引用this
了一个与self
另一个.语义有什么不同吗?如果没有,是否有一种风格上的理由偏爱一个而不是另一个?
我试图弄清楚如果该文档尚未存在于该集合中,如何将文档插入到集合中.如果文档已经存在,则该语句应为no-op.
我采用的方法是使用带有空更新文档的upsert:
db.collection.update({ ...query... }, { }, { upsert: true })
Run Code Online (Sandbox Code Playgroud)
但Mongo告诉我"更新文件不能为空".如何在不必要地更新现有文档的情况下完成此操作?谢谢.
编辑:我的查询文档如下所示:
{
"Chromosome" : "4",
"Position" : 60000,
"Identifier" : "rs1345",
"ReferenceAllele" : "N"
}
Run Code Online (Sandbox Code Playgroud) 我有TransformManyBlock
以下设计:
我在一个巨大的文件(61GB)上运行这个块,这个文件太大而无法放入RAM中.为了避免无限制的内存增长,我BoundedCapacity
为这个块和所有下游块设置了一个非常低的值(例如1).尽管如此,该块显然会贪婪地迭代IEnumerable,它消耗了计算机上的所有可用内存,使每个进程停止运行.在我杀死进程之前,块的OutputCount继续无限制地上升.
我该怎么做才能防止块IEnumerable
以这种方式消耗?
编辑:这是一个示例程序,说明了问题:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
class Program
{
static IEnumerable<string> GetSequence(char c)
{
for (var i = 0; i < 1024 * 1024; ++i)
yield return new string(c, 1024 * 1024);
}
static void Main(string[] args)
{
var options = new ExecutionDataflowBlockOptions() { BoundedCapacity = 1 };
var firstBlock = new TransformManyBlock<char, string>(c => GetSequence(c), options);
var secondBlock = new ActionBlock<string>(str …
Run Code Online (Sandbox Code Playgroud) .net ×4
c# ×4
f# ×3
64-bit ×1
dataflow ×1
delegates ×1
generics ×1
hql ×1
lambda ×1
left-join ×1
mongodb ×1
nhibernate ×1
random ×1
reflection ×1
sql-order-by ×1
tpl-dataflow ×1