使用向量进行 Scala 函数式编程
我是 Scala 编程新手,对函数式编程和不可变集合有一些困难。我正在尝试将我的数字代码从 C++ 移植到 Scala。
很多时候我的代码都在这样的小向量上运行:
double ytmp[6];
for (int i=0; i<6; i++) {
ytmp[i] = y[i] + h*(a41*dydx[i] + a42*k2[i] + a43*k3[i]);
}
How do I write like this in effective Scala?我一开始就考虑过使用简单的列表,但是不可变类型有问题,所以我不能像我习惯的 C++ 那样只创建一个空列表 ytmp 并稍后修改它。 感谢您的帮助
I am new to Scala programming and have some difficulty with functional programming and immutable collections. I am trying to port my numeric code from C++ to Scala.
A lot of time I have code operating on small vector like this:
double ytmp[6];
for (int i=0; i<6; i++) {
ytmp[i] = y[i] + h*(a41*dydx[i] + a42*k2[i] + a43*k3[i]);
}
How do I write something like this in efficient Scala? I thought about using simple lists in the beginning, but have problems with the immutable types, so I can't just create a empty list ytmp and modify it later like I am used to i C++.
Thanks for the help
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
为了提高效率,您可以以完全相同的方式编写此代码(注意,这不是函数代码),除了使用 while 循环。 For 循环被转换成极其低效(但非常通用和强大)的结构。因此,在这种情况下,您(警告,未经测试):
通常,它的运行速度与您的 C++ 代码一样快。
一旦您将这样的原始内容包装到类中,然后使用
map
、foreach
等操作大量这些类,您就会开始从 Scala 中受益。但对于数字代码,要么编写漂亮但速度慢得令人尴尬的代码(从 C++ 的角度来看),要么编写丑陋但性能不错的代码(是的,与类 C C++ 相比丑陋)。
因为我经常这样做,所以我尝试将这些丑陋但快速的代码放入漂亮的库中,然后尽可能地忘记它并在库启用的更高级别上工作。
For efficiency, you write this exactly the same way (note, this is not functional code), except with a while loop. For loops are converted into incredibly inefficient (yet splendidly general and powerful) constructs. So, in this case, you (warning, untested):
which will run about as fast as your C++ code, typically.
You start to benefit from Scala once you wrap primitive stuff like this into classes, and then operate on large numbers of those classes with
map
,foreach
, and so on.But for numeric code, either you write pretty but embarrassingly slow code (from a C++ perspective), or ugly but decently-performing code (yes, ugly compared to C-like C++).
Since I do this a lot, I try to put this ugly but fast code in nice libraries and then forget about it as much as possible and work at the higher level enabled by the libraries.
我是这样写的:
所以,这是第一次转换,除非我犯任何错误,否则应该做同样的事情。还有其他注意事项,例如使用不可变集合而不是数组,或者在创建时初始化数组。但是,对于您正在编写的代码类型来说,数组会更快。数组初始化的一个有趣的选项是:
但是,我不确定 tabulate 是否会为您提供相同的性能。或许。
This is how I'd write it:
So, this is a first transformation, which, barring any mistakes on my part, should do the same thing. There are other considerations like using an immutable collection instead of
Array
, or initializing the array at the time of creation. However, arrays will be faster for the kind of code you are writing. One interesting option for array initialization would be this:However, I'm not sure
tabulate
will give you the same performance. Maybe.这是另一种可能性 - 不知道它是否高性能等:
它返回一个数组
Here's another possibility - no idea if its performant etc:
which returns an array
您可以尝试类似的
值 v 将是使用 Vector 实现的 IndexedSeq,Vector 是为索引查找构建的不可变类型。
You could try something like
The value v will be an IndexedSeq implemented using a Vector, which is an immutable type built for indexed lookups.
这是另一套班轮,但我怀疑性能会很差:
Here is another one liner but I suspect the performance will be bad:
这个问题有很多不同的解决方案,非常感谢。特别是对于基准数字。所以我想我会坚持使用“.view.zipWithIndex”解决方案并希望速度足够好,否则我必须回到 while 循环。
我面临的另一个小问题。
我需要这样的东西:
如果我理解正确,我应该总是在列表前面添加。
所以这就是我要做的:
这是一个好主意,还是有更好的性能解决方案?
puh there are a lot of different solutions to this problem, thanks very much. Especially for the benchmark numbers. So I think I will stick with the ".view.zipWithIndex" solution and hope the speed is good enough, otherwise I have to go back to while loops.
Another short problem I face.
I need something like this:
If i understand it right I should always prepend to a list.
So this is how I would do it:
Is this a good idea, or is there a better solution for the performance ?