以下是 Mastering Dyalog APL 书中关于内部积的章节的摘录:

HMS is a variable which contains duration in Hours, Minutes, and Seconds: HMS ← 3 44 29 Chapter J – Operators 397

We would like to convert it into seconds. We shall see 3 methods just now, and a 4th
 method
will be given in another chapter.
    A horrible solution                        (3600×HMS[1]) + (60×HMS[2]) + HMS[3]
    A good APL solution                        +/ 3600 60 1 × HMS
    An excellent solution with Inner Product   3600 60 1 +.× HMS

然后它说第二个和第三个解决方案在键入的字符数 和性能 方面是等效的。

据我了解,APL 程序员一般应该尽可能多地使用内积和外积。那是对的吗?

你能举一个例子,当使用内积会导致性能提升吗?当我使用内积(在较低级别)时到底会发生什么?下面介绍的第一个解决方案是否很糟糕,因为它没有以正确的方式使用 APL 语法还是实际上性能更差?

我知道有几个问题,但我想问的是 内部/外部产品如何工作以及 APL 程序员何时应该使用它们

最佳答案



这真的取决于 APL 程序员和手头的任务,但如果有什么能让 APL 代码更简洁和高效,我不明白为什么程序员不会选择它。

在这种特殊情况下,60⊥HMS 比内积更简洁、更高效。



正如在面向数组的编程中一样,性能提升是通过一次性完成的。
大多数 APL 函数都是隐式循环——它们的实现使用一个计数器、一个限制和一个增量步。
你的代码越短越好,因为它不仅更容易记住,而且效率也更高,因为解释器必须对数据进行更少的传递。
一些实现进行循环融合以试图减少这种开销。
有些具有习语识别功能——某些波浪线组合在解释器中是特殊情况。一次性完成还允许解释器进行巧妙的优化,例如使用 SSE 指令集或 GPU。

回到内积,让我们以 A f.g B 为例,其中 AB 是向量,看看 fg 是如何应用的(在 Dyalog 中):

      f←{⎕←(⍕⍺),' f ',⍕⍵ ⋄ ⍺+⍵}
      g←{⎕←(⍕⍺),' g ',⍕⍵ ⋄ ⍺×⍵}
      0 1 2 3 4 f.g 5 6 7 8 9
4 g 9
3 g 8
24 f 36
2 g 7
14 f 60
1 g 6
6 f 74
0 g 5
0 f 80
80

从上面可以看出,对 fg 的调用是交错的。解释器同时处理 f 并减少 g,一次性完成,避免创建临时数组,就像 f/ A g B 所做的那样。

另一个例子:http://archive.vector.org.uk/art10500200

您可以自己测试不同解决方案的性能,看看哪一个最有效:
      )copy dfns.dws cmpx
      ⍝ or: ")copy dfns cmpx" if you are using Windows
      HMS ← 3 44 29
      cmpx '(3600×HMS[1]) + (60×HMS[2]) + HMS[3]' '+/ 3600 60 1 × HMS' '3600 60 1 +.× HMS' '60⊥HMS'
  (3600×HMS[1]) + (60×HMS[2]) + HMS[3] → 2.7E¯6 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  +/ 3600 60 1 × HMS                   → 9.3E¯7 | -66% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  3600 60 1 +.× HMS                    → 8.9E¯7 | -68% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  60⊥HMS                               → 4.8E¯7 | -83% ⎕⎕⎕⎕⎕⎕⎕

关于matrix - 了解 APL 的内积,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24141989/

10-12 17:41