下面的程序似乎非常低效.它需要多达28.980 GC时间,相比之下6.361秒非GC时间,SBCL为1.0.53.
(deftype vec3 () '(simple-array double-float (3)))
(declaim (inline make-vec3 vec3-zero
vec3-x vec3-y vec3-z
vec3-+))
(defun make-vec3 (x y z)
(declare (optimize (speed 3) (safety 0)))
(make-array 3 :element-type 'double-float
:initial-contents (list x y z)))
(defun vec3-zero ()
(make-vec3 0.0d0 0.0d0 0.0d0))
(defun vec3-x (x)
(declare (optimize (speed 3) (safety 0)))
(declare (type (simple-array double-float (3)) x))
(aref x 0))
(defun vec3-y (x)
(declare (optimize (speed 3) (safety 0)))
(declare (type (simple-array double-float (3)) x))
(aref x 1))
(defun …
Run Code Online (Sandbox Code Playgroud) 我想映射申请表格.
类似地图的函数类型如下:
mapX :: (Applicative f) => (f a -> f b) -> f [a] -> f [b]
Run Code Online (Sandbox Code Playgroud)
用作:
result :: (Applicative f) => f [b]
result = mapX f xs
where f :: f a -> f b
f = ...
xs :: f[a]
xs = ...
Run Code Online (Sandbox Code Playgroud)
作为这篇文章的背景,我尝试用Paul Haduk的"The Haskell School of Expression"使用Applicative样式编写流体模拟程序,我想用Applicative样式表达模拟如下:
x, v, a :: Sim VArray
x = x0 +: integral (v * dt)
v = v0 +: integral (a * dt)
a = (...calculate acceleration …
Run Code Online (Sandbox Code Playgroud) 初始化数据结构或对象时,如果子对象在使用后需要显式释放过程,那么在初始化过程中如何处理错误?
让我举个例子,用SUBOBJ1和SUBOBJ2槽初始化一个OBJECT对象,设置指向int值的外部指针:
(defun init-object ()
(let ((obj (make-object)))
(setf (subobj1 obj) (cffi:foreign-alloc :int)
(subobj2 obj) (cffi:foreign-alloc :int))
obj))
Run Code Online (Sandbox Code Playgroud)
如果我们在SUBEJ2插槽的FOREIGN-ALLOCing中出错,我们应该为SUBOBJ1插槽执行FOREIGN-FREEing以避免内存泄漏.
作为一个想法,我可以写如下:
(defun init-object ()
(let ((obj (make-object)))
(handler-case
(setf (subobj1 obj) (cffi:foreign-alloc :int)
(subobj2 obj) (cffi:foreign-alloc :int))
(condition (c) ; forcedly handling all conditions
(when (subobj1 obj) (cffi:foreign-free (subobj1 obj)))
(error c))) ; invoke the condition c again explicitly
obj))
Run Code Online (Sandbox Code Playgroud)
你有更好的想法,或一般惯用的模式?
谢谢
在答案之后,我使用UNWIND-PROTECT添加代码.它不起作用,因为即使所有分配都成功完成,解除分配形式也会运行.
(defun init-object ()
(let ((obj (make-object)))
(unwind-protect
(progn
(setf (subobj1 obj) (cffi:foreign-alloc :int)
(subobj2 obj) (cffi:foreign-alloc :int))
obj) …
Run Code Online (Sandbox Code Playgroud)