小编Guy*_*der的帖子

F#与C#性能签名与示例代码

关于这个话题已经有很多讨论,但我都是关于鞭打死马,特别是当我发现他们可能还在呼吸时.

我正在研究解析CSV的异常和异国情调的文件格式,为了好玩,我决定用我知道的2 .net语言C#和F#来表征性能.

结果......令人不安.F#大幅提升了2倍或更多(实际上我认为它更像是.5n,但是由于我正在测试硬件IO,因此获得真正的基准测试很难).

像读取CSV这样常见的性能特征让我感到惊讶(请注意,系数意味着C#在非常小的文件上获胜.我正在进行的测试越多,感觉C#的表现越差,这既令人惊讶又令人关注,因为它可能意味着我做错了).

一些笔记:Core 2 duo笔记本电脑,主轴磁盘80演出,3演出ddr 800内存,Windows 7 64位溢价,.Net 4,没有打开电源选项.

第一次运行后30,000行5宽1短语10个字符或更少给我3个支持尾调用递归(它似乎缓存文件)

对于尾部调用递归,300,000(重复相同的数据)是2的因子,F#的可变实现略微胜出,但性能签名表明我正在击中磁盘而不是ram-disking整个文件,这会导致半随机性能尖峰.

F#代码

//Module used to import data from an arbitrary CSV source
module CSVImport
open System.IO

//imports the data froma path into a list of strings and an associated value
let ImportData (path:string) : List<string []> = 

    //recursively rips through the file grabbing a line and adding it to the 
    let rec readline (reader:StreamReader) (lines:List<string []>) : List<string []> =
        let line = reader.ReadLine()
        match line with …
Run Code Online (Sandbox Code Playgroud)

c# performance f# tail-recursion

7
推荐指数
2
解决办法
2532
查看次数

为什么parsecs"选择"组合似乎坚持第一选择?

在查看Real World Haskell中的CSV示例代码之后,我尝试构建一个小的XML解析器.但是关闭标签会因"意外"/"错误而错误输出.你能告诉我为什么我的"closeTag"解析器不起作用(或者可能不会被调用)吗?谢谢!

import Text.ParserCombinators.Parsec

xmlFile = manyTill line eof
line = manyTill tag eol
eol = char '\n'

word = many1 (noneOf "></")

tag = choice [openTag, closeTag, nullTag, word]

nullTag = between (char '<') (string "/>") word
closeTag = between (string "</") (char '>') word
openTag = between (char '<') (char '>')  tagContent
attrval = between (char '"') (char '"') word

atts = do {
        (char ' ')
        ; sepBy attr (char ' ')
}

attr = do …
Run Code Online (Sandbox Code Playgroud)

xml haskell parsec

7
推荐指数
1
解决办法
923
查看次数

优化Haskell XML解析器

我现在正在试验Haskell并且非常享受这种体验,但我正在评估它是否具有一些相当严格的性能要求的真实项目.我的任务的第一步是处理维基百科的完整(无历史)转储(bzip) - 总共约6Gb压缩.在python中,每个原始页面(总共大约1000万)的完整提取的脚本在我的盒子上大约需要30分钟(对于参考,使用pull解析器的scala实现大约需要40分钟).我一直试图使用Haskell和ghc复制这个性能,并且一直在努力匹配这个.

我一直在使用Codec.Compression.BZip进行解压缩,使用hexpat进行解析.我使用lazy bytestrings作为hexpat的输入,使用严格的字节串作为元素文本类型.为了提取每个页面的文本,我正在构建一个指向文本元素的指针的Dlist,然后迭代它以将其转储到stdout.我刚刚描述的代码已经通过了许多分析/重构迭代(我很快从字符串转换到字节串,然后从字符串连接转移到指向文本的指针列表 - 然后转到指向文本的指针列表).我认为我从原始代码中获得了大约2个数量级的加速,但它仍需要一个半小时来解析(尽管它有一个可爱的小内存占用).所以我正在寻找社区的一些灵感,让我更加努力.代码如下(为了从分析器中获取更多细节,我将其分解为许多子功能).请原谅我的Haskell - 我只编写了几天(与Real World Haskell共度了一个星期).并提前感谢!

import System.Exit
import Data.Maybe
import Data.List
import Data.DList (DList)
import qualified Data.DList as DList

import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy as LazyByteString
import qualified Codec.Compression.BZip as BZip

import Text.XML.Expat.Proc
import Text.XML.Expat.Tree
import Text.XML.Expat.Format

testFile = "../data/enwiki-latest-pages-articles.xml.bz2"

validPage pageData = case pageData of
    (Just _, Just _) -> True
    (_, _) -> False

scanChildren :: [UNode ByteString] -> DList ByteString
scanChildren c = case c …
Run Code Online (Sandbox Code Playgroud)

xml performance haskell

7
推荐指数
1
解决办法
1019
查看次数

为Dictionary <'K,'V>键入扩展错误

以下类型扩展名

module Dict =

  open System.Collections.Generic

  type Dictionary<'K, 'V> with
    member this.Difference(that:Dictionary<'K, 'T>) =
      let dict = Dictionary()
      for KeyValue(k, v) in this do
        if not (that.ContainsKey(k)) then
          dict.Add(k, v)
      dict
Run Code Online (Sandbox Code Playgroud)

给出错误:

签名和实现不兼容,因为类型参数'TKey'的声明需要形式为'TKey:equality的约束

但是当我添加约束时,它会给出错误:

此类型扩展的声明类型参数与原始类型"Dictionary < , >" 上的声明类型参数不匹配

这尤其神秘,因为以下类型扩展没有约束并且有效.

type Dictionary<'K, 'V> with
  member this.TryGet(key) =
    match this.TryGetValue(key) with
    | true, v -> Some v
    | _ -> None
Run Code Online (Sandbox Code Playgroud)

现在我有一些奇怪的想法:只有在访问某些成员时才需要约束吗?

extension-methods f# dictionary

7
推荐指数
1
解决办法
458
查看次数

什么是Prolog运算符^?

什么是Prolog运算符^?

查看Prolog内置指令op,列出了内置运算符.

我看
**是取幂
/ \是或

但是^是什么?

当前三个答案中的每一个都是有价值的,我学到了一些东西:

  • 罗伊为这本书
  • 这个例子是假的
  • 我接受了CapelliC的答案,因为它明确表示^/2具有多种含义,
    具体取决于上下文,立即消除了我的困惑.

lambda prolog exponentiation iso-prolog prolog-setof

7
推荐指数
3
解决办法
1517
查看次数

运行使用FSharp.Data的单元测试时出现MissingMethodException

我有一个NUnit单元测试,它是用普通的F#库编写的,但它是针对可移植类库中的F#代码.

当我运行此测试(在Visual Studio 2013中)时,我得到以下异常:

Result Message: System.MissingMethodException : Method not found:
 'Microsoft.FSharp.Control.FSharpAsync`1<System.IO.TextReader> FSharp.Data.Runtime.IO.asyncReadTextAtRuntime(System.Boolean, System.String, System.String, System.String, System.String)'.
Run Code Online (Sandbox Code Playgroud)

这就是我在Portable Class Library中的app.config中所拥有的:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.3.1.0" newVersion="3.3.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)

这就是我在普通F#库的app.config中所拥有的:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.3.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.6.3.13283" newVersion="2.6.3.13283" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)

f# missingmethodexception f#-data

7
推荐指数
1
解决办法
962
查看次数

内联函数和类型扩展

考虑我有两种不同的类型:

type Foo = { foo : string }
type Bar = { bar : int32 }
Run Code Online (Sandbox Code Playgroud)

我想实现zoo适用于任一个FooBar实例的泛型函数.我无法改变Foo,Bar因为它们是图书馆代码的一部分.

下面是使用类型扩展和内联函数的解释了我的第一次尝试在这里:

// Library.fs
module Library

type Foo = { foo : string }
type Bar = { bar : int32 }

// Program.fs
type Foo with
    static member zoo (f : Foo) = "foo"

type Bar with
    static member zoo (b : Bar) = "bar"

let inline …
Run Code Online (Sandbox Code Playgroud)

f# inline

7
推荐指数
1
解决办法
194
查看次数

如何识别重新定义的变量或阴影变量

在F#编译器的同一范围内使用相同的变量两次时,没有警告或反馈.例如

let s = "abc"
let s = "def"
printfn "%A" s
Run Code Online (Sandbox Code Playgroud)

结果是

def
Run Code Online (Sandbox Code Playgroud)

我已经看到
有没有办法在Visual Studio中对F#中的值进行阴影警告?
F#值阴影 - 是否可以在同一范围内禁用值阴影

有没有办法通过编译器警告或在编辑器中可视化获得有关阴影变量的反馈.如何才能做到这一点?

f# shadowing

7
推荐指数
1
解决办法
182
查看次数

在F#中,顶级意味着什么?

当人们谈论F#时,他们有时会提到这个词top-level;

什么top-level意思?

例如在之前的SO Q&A中

错误FS0037有时,非常混乱
定义模块VS.NET与F#Interactive F#中
命名空间和模块之间的区别是什么?
F#
F#和MEF中的 AutoOpen属性:导出函数如何执行此F#函数

该术语也会在评论中定期出现,但对于那些问答我没有提及.

关于范围的维基百科文章涉及到这一点,但没有F#的具体细节.

F#3.x规范仅规定:

11.2.1.1函数和值的Arity一致性

括号表示一个top-level函数,它可能是计算函数值的第一类计算表达式,而不是编译时函数值.

13.1自定义属性

例如,STAThread属性应该放在top-level"do"语句之前.

14.1.8类型变量的名称解析

对于top-level包含表达式和类型的任何成员或任何其他构造,它最初为空.

我怀疑这个术语在不同的语境中有不同的含义:范围,F#交互,阴影.

如果您还可以解释F#前身语言(ML,CAML,OCaml)的起源,我们将不胜感激.

最后,我不打算将答案标记为几天,以避免仓促答案.

f# scope shadowing toplevel

7
推荐指数
1
解决办法
335
查看次数

F#Tuple Constant永远不会初始化

我已经宣布了这样一个元组:

module MyModule =
  let private INVALID_TUPLE = ("0", DateTime.MinValue)
Run Code Online (Sandbox Code Playgroud)

当我在模块中引用它时,它总是为null:

let private invalidForNone someOtherTuple =
  match someOtherTuple with
  | None -> INVALID_TUPLE  // it's null
  | Some(t) -> t
Run Code Online (Sandbox Code Playgroud)

此外,当我在元组声明上放置一个断点时,它永远不会命中.

如果我在脚本(fsx)文件中执行完全相同的操作,启动调试,执行,元组声明命中的断点以及对元组的引用是好的.

ILSpy for my module显示生成了一些启动代码,其中包含一个创建INVALID_TUPLE的Main方法.显然,这不是出于某种原因运行?

这是一个重现行为的示例(现在我意识到它与MSTest执行代码的方式有关).从C#单元测试中调用它; 结果将为null.实际上,F#代码中的断点根本不会执行.

module NullTupleTest
open System

let private INVALID_TUPLE = ("invalid", DateTime.MinValue)

let private TupleTest someTuple =
  match someTuple with
  | None -> INVALID_TUPLE
  | Some(dt) -> dt

let Main = TupleTest None
Run Code Online (Sandbox Code Playgroud)

f# program-entry-point tuples libraries

7
推荐指数
1
解决办法
94
查看次数