首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >了解APL的内部产品

了解APL的内部产品
EN

Stack Overflow用户
提问于 2014-06-10 13:14:36
回答 3查看 675关注 0票数 5

这是摘录自精通Dyalog APL的书,摘自关于内部产品的一章。

代码语言:javascript
复制
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程序员应该在什么时候使用

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-06-11 14:48:12

APL程序员应该尽可能多地使用内部产品和外部产品。对吗?

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

在这种情况下,60⊥HMS甚至比内部积更简洁和高效。

您能给出一个例子,当使用内部产品会带来性能的提高吗?

作为典型的面向数组的编程,性能提高是通过一蹴而就的方式实现的。大多数APL函数都是隐式循环--它们的实现使用计数器、限制和增量步骤。代码越短,越好,因为它不仅更容易掌握在一个人的头脑中,而且效率更高,因为解释器必须完成更少的数据传递。为了减少这种开销,一些实现进行了循环融合。有些人有成语识别-在翻译中有一些特殊的组合。一次完成任务还允许解释器进行聪明的优化,比如使用SSE指令集或GPU。

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

代码语言:javascript
复制
      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的调用是交织的。解释器可以同时减少fg,避免创建临时数组,就像f/ A g B所做的那样。

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

您可以为自己测试不同解决方案的性能,并查看哪种解决方案最有效:

代码语言:javascript
复制
      )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% ⎕⎕⎕⎕⎕⎕⎕
票数 5
EN

Stack Overflow用户

发布于 2014-06-13 12:16:05

我们已经完成了优化+/和+.×的工作。

MBaas是正确的,因为在这个实例中,+/比+.×略好一些。

我们的一般建议是:在最适合作业的语言中使用构造,最终实现会迎头赶上。

“可怕”的解决方案被认为是不好的,因为它不使用数组思维。

致以敬意,

文斯,Dyalog支持

票数 6
EN

Stack Overflow用户

发布于 2014-06-11 11:27:50

泛化的问题是,它们可能是不正确的,但根据经验,我认为使用内部和外部产品将有利于可读性和性能;-)

现在,看看实践中的事情:

Performance.RunTime (3600×HMS1)+(60×HMS2)+HMS3 -repeat=100000

  • 基准测试“(3600×HMS1)+(60×HMS2)+HMS2 3”,repeat=100000 Exp (avg):0.001558503836累加: 0.001618446292 ]performance.RunTime '+/ 3600 60 1×HMS‘-repeat=100000
  • 基准测试"+/ 3600601×HMS",repeat=100000 Exp (avg):0.0004698496481次运行: 0.0004698496481‘

这是一个相当大的差别--如果您重复了足够多的时间来测量它;--但是当然,对于更大的数据集,优势变得更明显了!让我们看一下3种变体:

[performance.RunTime '3600 60 1 +.×HMS‘-repeat=100000

  • 基准测试“3600601 +.×HMS",repeat=100000 Exp (avg):0.0004698496481次运行: 0.000439859245次 `

这里没有什么区别,但同样-与“真实数据”(更大的数组),您应该会看到一个更清楚的区别。我认为一个简单的解释是,内部积就像解释器的一个‘语句’,而第一个变体有3个单一的乘法,索引,需要考虑优先级(括号),然后总结这个向量,这听起来很费劲;-)第二个语句只有一个乘法(对于一个向量),所以它已经消除了几个步骤,而内部积使得解释器可以结合一些内部工作来更快地完成他的工作。

现在有一个惊喜: v1←(10000/3600 60 1)⋄v2←10000/HMS ]performance.RunTime '+/v1×v2‘v1 +.×v2’-repeat=100000 -compare

代码语言:javascript
复制
  +/v1 × v2 → 6.0E¯5 |  0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕   
  v1 +.× v2 → 6.3E¯5 | +5% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ 

我原以为更大的论据将有助于使最后一个表达式的性能--优势更明显--但实际上第二名获胜了。也许Dyalog优化的案例2多于#3.;-)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24141989

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档