在Common Lisp中,我可以在子网格上进行就地算术运算吗?

时间:2013-09-24 08:13:09

标签: grid common-lisp in-place

我正在使用AntikGsll进行矩阵计算。

有时我想在子网格上进行算术运算(例如,将矩阵的列乘以2.0)。现在我必须写下这些代码:

(setf (grid:column mat 0) (gsll:elt* (grid:column mat 0) 2.0))

根据这些代码,Antik必须首先创建一个临时网格来存储中间结果,然后将其设置为原始mat。当矩阵很大时,临时网格的创建可能很慢。所以我希望我可以直接在原mat上完成这项工作。

PS: gsll:elt*对整个矩阵进行就地修改,例如(gsll:elt* mat 2.0),即使mat很大,这也非常有效。

更新

我在这里展示了我的实验结果:

代码:

(let ((mat (grid:make-simple-grid
             :grid-type 'grid:foreign-array
             :initial-contents
             (loop repeat 100 collect
                   (loop repeat 100 collect
                         (random 100))))))
  (time (loop repeat 1000 do
              (gsll:elt* mat 2.0)
              (gsll:elt* mat 0.5)))
  (time (loop repeat 1000 do
              (setf (grid:row mat 0) (gsll:elt* (grid:row mat 0) 2.0))
              (setf (grid:row mat 0) (gsll:elt* (grid:row mat 0) 0.5)))))

结果:

Evaluation took:
  0.016 seconds of real time
  0.016000 seconds of total run time (0.016000 user, 0.000000 system)
  100.00% CPU
  46,455,124 processor cycles
  353,280 bytes consed

Evaluation took:
  0.446 seconds of real time
  0.444000 seconds of total run time (0.420000 user, 0.024000 system)
  [ Run times consist of 0.008 seconds GC time, and 0.436 seconds non-GC time. ]
  99.55% CPU
  1,308,042,508 processor cycles
  102,275,168 bytes consed

请注意,前一个计算是在整个100x100矩阵上进行的,这比后者更快(仅采用1x100子矩阵)。后者由于临时存储的分配而产生了更多的字节。

0 个答案:

没有答案