.net F#visual studio和命令行生成之间的执行速度差异

.net F#visual studio和命令行生成之间的执行速度差异,.net,visual-studio,.net-core,f#,.net,Visual Studio,.net Core,F#,使用F#visual studio(community 2019)构建的程序与使用F#命令行(均使用F#4.7)构建的程序在执行时间上存在显著差异。我的问题是:为什么会有这种差异 我使用的是Windows10家庭版1809(最新版本)。该程序主要在Pollard rho分解算法中使用大整数(程序如下)。对于VisualStudio,我使用了一个控制台项目 visual studio的运行时间为28秒,命令行为39秒 我在这两个平台上都为x64目标使用了一个发布二进制文件。我尝试了许多fsc编译命

使用F#visual studio(community 2019)构建的程序与使用F#命令行(均使用F#4.7)构建的程序在执行时间上存在显著差异。我的问题是:为什么会有这种差异

我使用的是Windows10家庭版1809(最新版本)。该程序主要在Pollard rho分解算法中使用大整数(程序如下)。对于VisualStudio,我使用了一个控制台项目

visual studio的运行时间为28秒,命令行为39秒

我在这两个平台上都为x64目标使用了一个发布二进制文件。我尝试了许多fsc编译命令行选项(--debug---optimize+--standalone),没有任何明显的区别

命令行编译输出为

 7168 Nov  2 16:14 rho.exe
 10752 Nov  2 09:12 rho0.dll*
159744 Nov  2 09:12 rho0.exe*
对于命令行

fsc rho.fs
如上所述,添加命令行选项并没有多大区别

VisualStudio的输出是

 7168 Nov  2 16:14 rho.exe
 10752 Nov  2 09:12 rho0.dll*
159744 Nov  2 09:12 rho0.exe*
因此,输出非常不同。rho和rho是同一个源

两个版本产生相同的答案,但经过的时间差异很大。为什么?

该计划是:

open System
open System.Diagnostics
open System.Numerics

type Z = System.Numerics.BigInteger

let rho n maxIter c1 =
  let mutable iter = 1
  let mutable prod = 1I
  let mutable x    = 2I
  let mutable y    = 11I
  let mutable gcd  = 0I
  let mutable solution = false

  let stopWatch = Stopwatch();
  stopWatch.Start()

  while not solution do
    x <- (x * x + c1) % n;
    y <- (y * y + c1) % n;
    y <- (y * y + c1) % n;
    prod <- ((y - x) * prod) % n;
    if (iter % 150 = 0) 
    then
      gcd <- Z.GreatestCommonDivisor (n, prod)
      if (gcd <> 1I) then
        stopWatch.Stop()
        printfn "rho c1 = %A" c1
        printfn "factor, iterations = %A, %A" gcd iter
        printfn "elpased time = %A" stopWatch.ElapsedMilliseconds
        solution <- true
      else
        prod <- 1I
        iter <- iter+1
    else
      iter <- iter+1
  if (not solution) then
    printfn "no solution, iterations = %A" iter
  else printfn "solution"


let n = Z.Pow(2I,257) - 1I
let maxIter = 30000000
printfn "calling rho"
let result = rho n maxIter 7I
开放系统
开放系统诊断
开放系统。数字
类型Z=System.Numerics.BigInteger
设rhon-maxIter c1=
设可变iter=1
设可变产品=1I
设可变x=2I
设可变y=11I
设可变gcd=0I
设可变解=false
让秒表=秒表();
秒表开始
虽然不是解决方案

x我使用了您的示例代码,并通过不同的配置运行了它:

.NET Core from VS Release x64 - 37214 ms with (9171, 3, 0) CC
.NET Core from VS Release x86 - 69903 ms with (7673, 6, 0) CC
.NET Core from VS Release Any - 35694 ms with (9171, 3, 0) CC

.NET Core using EXE Release x64 - 37995 ms with (9171, 3, 0) CC
.NET Core using EXE Release x86 - 72489 ms with (7673, 7, 0) CC
.NET Core using EXE Release Any - 36106 ms with (9171, 3, 0) CC

.NET Framework 4.7.2 from VS Release x64 - 49697 ms with (5935, 4, 0) CC
.NET Framework 4.7.2 from VS Release x86 - 81324 ms with (4945, 8, 0) CC
.NET Framework 4.7.2 from VS Release Any - 80521 ms with (4945, 8, 0) CC

.NET Framework 4.7.2 using EXE Release x64 - 49450 ms with (5935, 4, 0) CC
.NET Framework 4.7.2 using EXE Release x86 - 80418 ms with (4945, 8, 0) CC
.NET Framework 4.7.2 using EXE Release Any - 80458 ms with (4945, 8, 0) CC

.NET Core using dotnet run x64 - 37614 ms with (9171, 3, 0) CC
.NET Core using dotnet run no tiered compilation x64 - 37186 ms with (9171, 3, 0) CC
从这一点来看,
x86
x64
之间似乎有很大的区别。您是否尝试过在VS和from命令行中强制使用
x64
模式。DLL可以编译为任何类型,但仍首选x86

此外,;从我的测试来看,.NETCore的性能似乎比.NETFramework4.72要好

我曾尝试在.NETCore中禁用分层编译,有时也会导致性能问题,但没有发现任何真正的区别

我意识到这在StackOverflow中是不受欢迎的,但由于项目配置可能很难放到文章中,我决定在这里使用示例代码:

OP可以看看是否有可能在OPs机器上复制我的号码

所以从我的角度来看.NETCore看起来比.NETFramework好,但为什么呢

通过
dnSpy
查看代码,我看不出.NET核心的OP代码与.NET Framework的OP代码之间有什么显著差异。但是,通过查看
System.Numerics
依赖关系,我可以发现.NET核心版本和.NET Framework版本的
System.Numerics
之间存在一些非常显著的差异

该版本在.NET Core中较新,适用于
System.Numerics
,但不确定它们是否遵循相同的版本控制(
4.1.2.0
适用于.NET Core,而
4.0.0.0
适用于.NET Framework)


因此,从我的角度来看,底线是,确保使用
x64
和.NET内核。

在F#中有很多值得喜欢的地方,但大整数的速度很慢。windows 10和linux上的Ocaml运行时间为10秒,而F#上的运行时间为28秒。在我看来,由于dll的存在,vs在这里似乎使用了dotnet核心。我会使用dnspy之类的工具来检查生成的输出。例如,使用的是同一个大整数吗?实际上你没有问任何问题。我的猜测是,不同之处可能在于目标框架。如果VS项目的目标是.NETCore,而fsc命令的目标是.NETFramework,那么这可能是造成差异的原因。您是否尝试过dotnet build或dotnet run?另外,请显示您运行的命令行。而且,您可以设置VS和fsc以返回详细的输出,以获得更多详细信息。您可以分享一个复制性能差异的独立示例吗?这样我就可以在本地构建它,看看会发生什么。F#控制台应用程序的默认框架是.NETCore3.0(运行时间28秒)。如果将VS项目更改为.NET Framewok 4.5.1,则运行时间为39秒。这是为什么??