gpt4 book ai didi

c# - 如何在保持其语法的同时使此函数式代码的性能更高

转载 作者:行者123 更新时间:2023-11-30 13:31:35 24 4
gpt4 key购买 nike

我想写这个操作

Matrix.Multiply(source,target)
target.Add(offsets)

以这种数学风格

target = Matrix * source + offsets;

但是,我也很关心性能。 (实际上,上述操作将在紧密循环中运行。)我不想为每个矩阵向量乘法创建一个新向量,并为向量加法创建另一个新向量。

如何在 C# 或 F#(或您知道的任何函数式语言)中实现上述操作,以便兼顾风格和性能?

很抱歉这个幼稚的问题。我确信这种愿望是如此根本。

最佳答案

一种众所周知的技术,例如 Repa 的核心高性能数值数组库,是在基本的“二维整数数组”结构之上定义一个更高级别的数据结构,延迟您要执行的操作,以及一个解释/归一化函数,最终将执行这些操作,应用它认为有利可图的任何优化。

具体来说,在您的示例中,我认为大多数当前答案都忽略了这一点,您希望将 A * B + C 重写为

add(multiply(A,B), C)

或面向对象风格电子

A.multiply(B).add(C)

而是

multiply_and_add(A,B,C)

其中 multiply_and_add 是一个特殊的、较低级别的操作,它同时执行这两个操作并且更加优化。类似地,众所周知,对于任意矩阵 A、B、C、D,乘积 A * B * C * D 可以更有效地计算为 A * ((B * C) * D) 而不是 A * (B * (C * D))),具体取决于操作数维度。因此,纯本地方法(在整数数组上表达每个操作)不起作用,您需要表达式全局重写以获得最佳效率——就像 C++ 中的 hackish 模板库所做的那样。

解决方案是从int array array 移动到精化数据类型,例如:

type matrix =
| Raw of int array array
| Add of matrix * matrix
| Mult of matrix * matrix

然后提供一个 eval : matrix -> int array array 函数,通过可能应用特定领域的优化来“解释”那些矩阵描述(本质上是矩阵运算的抽象语法树)。举个简单的例子:

let rec eval = function
| Raw m -> m
| Add(Mult(a,b), c) | Add(c, Mult(a,b)) ->
multiply_and_add (eval a) (eval b) (eval c)
| Add (a, b) -> add (eval a) (eval b)
| Mult (a, b) -> mult (eval a) (eval b)

然后您可以定义您喜欢的语法糖,使 matrix 构造函数更易于阅读。

module Matrix = struct
let (!) m = Raw m
let (+) a b = Add (a, b)
let (*) a b = Mult (a, b)
end

let ... = eval Matrix.(!A * !B + !C)

关于c# - 如何在保持其语法的同时使此函数式代码的性能更高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20363978/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com