我试图将boost :: multi_array的性能与本机动态分配的数组进行比较,使用以下测试程序:
#include <windows.h>
#define _SCL_SECURE_NO_WARNINGS
#define BOOST_DISABLE_ASSERTS
#include <boost/multi_array.hpp>
int main(int argc, char* argv[])
{
const int X_SIZE = 200;
const int Y_SIZE = 200;
const int ITERATIONS = 500;
unsigned int startTime = 0;
unsigned int endTime = 0;
// Create the boost array
typedef boost::multi_array<double, 2> ImageArrayType;
ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);
// Create the native array
double *nativeMatrix = new double [X_SIZE * Y_SIZE];
//------------------Measure boost----------------------------------------------
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i) …Run Code Online (Sandbox Code Playgroud) 我正在开发一个C#程序,它将加载文件并获取诸如加载文件创建日期,修改日期,大小等信息.我需要知道的另一件事是加载的文件(executable.exe)是否与LARGEADDRESSAWARE标志链接.FileInfo类不提供此信息.
有谁知道如何在C#中找出给定的execute.exe是否与LARGEADDRESSAWARE标志链接(处理大于2 GB的地址)?
我一直在阅读关于F#3.0类型提供程序(例如这里),看起来它们基于一种编译时代码生成.在这方面,我想知道他们如何与Lisp宏进行比较.似乎F#3.0类型提供程序和Lisp宏都允许用户代码在编译时执行并引入编译器可用的新类型.任何人都可以对这个问题和细微差别有所了解吗?
根据F#的规格(见§6.5.7),for循环简单的通过整数界(int又名int32又名System.Int32)的限制start和stop,如
for i = start to stop do
// do sth.
Run Code Online (Sandbox Code Playgroud)
我想知道为什么要求这种类型的for循环的迭代界限int32.为什么不允许uint32?int64?bigint?
我知道序列迭代表达式(for ... in ...)可以迭代任意序列; 然而,这需要分配一个迭代器和调用MoveNext,Current什么不是,因此可能比普通循环效率低得多(增量计数器,比较,条件跳转).为避免这种情况,您将无法使用while和手动递增循环计数器......
奇怪的是,如果表达式包含在序列表达式中,F#确实允许非int32循环边界for,例如
seq { for i = 0I to 10I do
printfn "%A" i }
Run Code Online (Sandbox Code Playgroud)
所以,我想问题是:是否有一个特殊的原因只允许int32循环?为什么这个限制不适用于表达式中包含的for循环seq?
该属性System.Runtime.CompilerServices.MethodImplAttribute可用于向JIT编译器提供有关如何处理修饰方法的提示.特别是,该选项MethodImplOptions.AggressiveInlining指示编译器在可能的情况下内联受影响的方法.不幸的是,F#编译器在生成IL时似乎只是忽略了这个属性.
示例:以下C#代码
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Inc(int x) => x + 1;
Run Code Online (Sandbox Code Playgroud)
被翻译成
.method public hidebysig static int32 Inc(int32 x) cil managed aggressiveinlining
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: add
IL_0003: ret
}
Run Code Online (Sandbox Code Playgroud)
请注意"aggressiveinlining"标志.
但是这个F#代码
[<MethodImpl(MethodImplOptions.AggressiveInlining)>]
let inc x = x + 1
Run Code Online (Sandbox Code Playgroud)
变
.method public static int32 inc(int32 x) cil managed
{
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.1
IL_0003: add
IL_0004: ret
}
Run Code Online (Sandbox Code Playgroud)
没有"积极主动".我还尝试将该属性应用于适当类(type ...)的静态和非静态方法,但结果是相同的.
但是,如果我将它应用于自定义索引器,就像这样
type Dummy = …Run Code Online (Sandbox Code Playgroud) 我在Visual Studio 2010和Mono Develop 2.8上都开发了一个C#服务器.NET Framework 4.0
看起来这台服务器在Windows上比在Linux上表现得更好(在可扩展性方面).我使用Apache的ab工具在本机Windows(12个物理内核),8和12个内核Windows和Ubuntu虚拟机上测试了服务器可扩展性.
窗口响应时间非常平坦.当并发级别接近/克服核心数量时,它开始上升.
由于某种原因,Linux的响应时间要糟糕得多.从并发级别5开始,它们几乎呈线性增长.此外,8核和12核Linux VM的行为也相似.
所以我的问题是:为什么它在Linux上表现更差?(我该如何解决这个问题?).
请查看附带的图表,它显示了满足75%请求的平均时间作为请求并发的函数(范围栏设置为50%和100%).

我有一种感觉,这可能是由于mono的垃圾收集器.我尝试使用GC设置,但我没有成功.有什么建议吗?
一些其他背景信息:服务器基于HTTP侦听器,可快速解析请求并在线程池上对它们进行排队.线程池负责用一些密集的数学回复那些请求(计算约10秒的答案).
在C#中我可以使用:
string myBigString = @"
<someXmlForInstance>
<someChild />
</someXmlForInstance>
";
Run Code Online (Sandbox Code Playgroud)
如何在F#中做到这一点?
所以我有类似的东西:
[IO Blah, IO Blah, IO Blah]
Run Code Online (Sandbox Code Playgroud)
我真的只想要一个Blahs 列表,我该怎么做?
PS:是的,我在IO功能中工作.
使用.NET 4.0中的TPL启动新的仅限副作用的任务(即:不返回结果的任务)的自动方式是使用以下API:
Task Task.Factory.StartNew(Action<object>, object)
Run Code Online (Sandbox Code Playgroud)
但是为什么这个API的签名看起来不像这样
Task Task.Factory.StartNew<T>(Action<T>, T)
Run Code Online (Sandbox Code Playgroud)
或者像这样
Task Task.Factory.StartNew<T>(T, Action<T>)
Run Code Online (Sandbox Code Playgroud)
技术原因还是其他原因?
在F#中,有NativePtr模块,但它似乎只为其'add/get/set函数支持32位偏移,就像System.IntPtr一样.
有没有办法在F#中为本机指针(nativeptr <'a>)添加64位偏移量?当然,我可以将所有地址转换为64位整数,执行正常的整数运算,然后将结果再次转换为nativeptr <'a>,但这会花费额外的add和imul指令.我真的希望AGU执行地址计算.
例如,在C#中使用unsafe,你可以做类似的事情
void* ptr = Marshal.AllocHGlobal(...).ToPointer();
int64 offset = ...;
T* newAddr = (T*)ptr + offset; // T has to be an unmanaged type
Run Code Online (Sandbox Code Playgroud)
实际上你不能,因为类型参数没有"非托管"约束,但至少你可以用非泛型方式进行通用指针运算.
在F#中,我们终于得到了非托管约束; 但是如何进行指针运算呢?