Pointers 一个人怎么能写出达夫';F#中的s设备?
我正在编写一个性能非常高的程序,并且一直在使用C语言,但是有人告诉我函数式编程有多酷,所以我决定用F#重写它 不管怎么说,我在F#中很难复制算法的特殊函数是。它不是典型的迭代,而是展开循环,这样每次迭代可以复制8个字节,而不是一个字节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++ =
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)