Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers 一个人怎么能写出达夫';F#中的s设备?_Pointers_Loops_F#_Copy - Fatal编程技术网

Pointers 一个人怎么能写出达夫';F#中的s设备?

Pointers 一个人怎么能写出达夫';F#中的s设备?,pointers,loops,f#,copy,Pointers,Loops,F#,Copy,我正在编写一个性能非常高的程序,并且一直在使用C语言,但是有人告诉我函数式编程有多酷,所以我决定用F#重写它 不管怎么说,我在F#中很难复制算法的特殊函数是。它不是典型的迭代,而是展开循环,这样每次迭代可以复制8个字节,而不是一个字节 void copy_memory( char* to, char* from, size_t count ) { size_t n = (count+7)/8; switch( count%8 ) { case 0: do{ *to++ =

我正在编写一个性能非常高的程序,并且一直在使用C语言,但是有人告诉我函数式编程有多酷,所以我决定用F#重写它

不管怎么说,我在F#中很难复制算法的特殊函数是。它不是典型的迭代,而是展开循环,这样每次迭代可以复制8个字节,而不是一个字节

void copy_memory( char* to, char* from, size_t count ) {
    size_t n = (count+7)/8;
    switch( count%8 ) {
    case 0: do{ *to++ = *from++;
    case 7:     *to++ = *from++;
    case 6:     *to++ = *from++;
    case 5:     *to++ = *from++;
    case 4:     *to++ = *from++;
    case 3:     *to++ = *from++;
    case 2:     *to++ = *from++;
    case 1:     *to++ = *from++;
            }while(--n>0);
    }
}
这充分利用了case fallthrough和在C中跳转到循环中间的能力,据我所知,这是F#似乎缺少的不幸特性

我在MSDN上读了一些东西,并认为F的
匹配
功能将是最接近C的
开关的功能。所以,我开始写这段代码

open System.Reflection
let copyMemory (pTo : Pointer) (pFrom : Pointer) length =
    let n = (length + 7) / 8
    match n % 8 with
    | 0 ->
然后我就不知道该怎么办了。它不会让我在这里开始一个循环,然后在另一个案例中结束它


F#中是否有我可以用来完成case fall through和跳入循环中间的功能?如果你能为我做到这一点,我想我可以自己解决剩下的问题。

下面是用F##来处理记忆的惯用方法:-)

但这可能更符合达夫的精神

let inline (+>) s d = 
  NativePtr.read !s |> NativePtr.write !d
  s:= NativePtr.add !s 1
  d:= NativePtr.add !d 1

let copyMemory src dst count =
  let n = ref ((count + 7) / 8)
  let s, d = ref src, ref dst
  let 
    rec case_0() = s +> d; case_7()
    and case_7() = s +> d; case_6()
    and case_6() = s +> d; case_5()
    and case_5() = s +> d; case_4()
    and case_4() = s +> d; case_3()
    and case_3() = s +> d; case_2()
    and case_2() = s +> d; case_1()
    and case_1() = s +> d; decr n; if !n > 0 then case_0()
  match count % 8 with
  | 7 -> case_7() | 6 -> case_6()
  | 5 -> case_5() | 4 -> case_4()
  | 3 -> case_3() | 2 -> case_2()
  | 1 -> case_1() | _ -> case_0()
但说真的

System.Buffer.BlockCopy(src, 0, dest, 0, count)
F#中没有标签。不过,您可以用另一种方式展开循环

let copy (dst : nativeptr<byte>) (src : nativeptr<byte>) count =
    let mutable s = src
    let mutable d = dst

    for n in 1 .. count / 8 do
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)

    for n in 1 .. count % 8 do
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
let copy(dst:nativeptr)(src:nativeptr)计数=
设可变s=src
设可变d=dst
对于1中的n。。数到八
NativePtr.read s |>NativePtr.write d

It’祝你好运。。。我认为您必须直接发出IL代码;)达夫的设备在函数式语言或任何现代编译器上都没有意义,因为如果有意义的话,它们会像这样为您进行优化。我意识到我的第二个努力是有缺陷的,所以我用达夫的更忠实的翻译来代替它。
let copy (dst : nativeptr<byte>) (src : nativeptr<byte>) count =
    let mutable s = src
    let mutable d = dst

    for n in 1 .. count / 8 do
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)

    for n in 1 .. count % 8 do
        NativePtr.read s |> NativePtr.write d
        s <- NativePtr.ofNativeInt(NativePtr.toNativeInt s + nativeint 1)
        d <- NativePtr.ofNativeInt(NativePtr.toNativeInt d + nativeint 1)