Now what above the calculation above? The inner + operation returns a float 3.0. In above case 3.0 is a new float, possibly newly consed. Consing means that some data is allocated on the heap: cons cells, numbers, arrays.
#LET XF AND YF BE ADJACENT FLOATING POINT NUMBERS 32 BIT#
Each function call returns floats, actually 32 bit single-floats.
![let xf and yf be adjacent floating-point numbers let xf and yf be adjacent floating-point numbers](https://chemistry-europe.onlinelibrary.wiley.com/cms/asset/059f246f-40f6-41b6-8360-857a25d957f3/cssc202100055-toc-0001-m.png)
The consed memory is caused by allocating the floats. (declare (type float v1x v1y v1z v2x v2y v2z v3x v3y v3z v4x v4y v4z)) (multiple-value-bind (v1x v1y v1z v2x v2y v2z v3x v3y v3z v4x v4y v4z) (when (eql (get-wall-type cell wall-heading) :NORMAL) (unless (eq wall-heading (opposite-heading *active-player-heading*)) (let ((cell (cell-at dungeon-object x y))) (declare (optimize (speed 3) (space 0) (debug 0))) (EDIT) for is the function that used the calculate-wall-points function that troublesome function was later inlined with (declaim (inline calculate-wall-points)) just before calculate-wall-points's definition: (defun render-dungeon-room (dungeon-object x y) So where could this function's "mystery consing" be coming from? How would you more experienced Lisp programmers approach this tricky gremlin of a problem? Tried replacing 'case' with a 'cond' equivalent, just grasping for straws at this point, did not do anything either.
![let xf and yf be adjacent floating-point numbers let xf and yf be adjacent floating-point numbers](https://onlinelibrary.wiley.com/cms/asset/4370d2c6-074d-44ef-8a58-f6190f30138b/adma201901408-fig-0003-m.jpg)
This seems significant, but I can't quite wrap my head around what my next approach should be. Or, that could be a coincidence, with 48 bytes meaning something else (since a float is NOT 1 byte, I suspect is -is- something else). 48 = 4 * 12, perhaps those 4 case tests times 12 floats per 'values' call. was 'case' doing the consing? I do find it interesting that, mentioned earlier, that mystery number was 48. Strangely, this did NOT stop this function from being a consing-piggy! So.
![let xf and yf be adjacent floating-point numbers let xf and yf be adjacent floating-point numbers](https://www.coursehero.com/thumb/27/1a/271a01e7eeaf293d4e25c1f14678db7161411871_180.jpg)
What did I do to try to mitigate this? Just for experiment's sake, I modified the file to make a single wall-vertex-buffer global array, sized to fit 12 elements of type float, and modified both this function to modify it, and the calling function to read from it after calling this function (so it would constantly be updating one single set of 12 floats kept in the same place in memory, instead of allocating anything). Perhaps, I thought, it's internally just something like the function 'list', which, without a doubt, conses (the 'list' function's only purpose in the universe). Then I thought 'values' might be doing this. Strangely, the profiler did report this function consing slightly less. To summarize a couple of things I have tried to fix this:ĭoing a 'declare' to 'optimize' for 'speed' at 3 and everything else at 0 (both in this function, as well as the only function that calls it). (error "Not a valid heading passed for wall in function calculate-wall-points: ~A" wall))))) "Return the 4 vertices (12 floats) of a given dungeon cell wall" My function as-is, is as follows: (defun calculate-wall-points (x y wall) Still, 1) I generally don't prematurely optimize, and more importantly 2) I still don't like leaving certain bothersome itches like this un-scratched, and I wonder what else I could have done. Now, I can easily mitigate this performance problem by using OpenGL display lists within gameplay mode, and I suppose that is what I will go ahead and do.
![let xf and yf be adjacent floating-point numbers let xf and yf be adjacent floating-point numbers](https://www.mdpi.com/cancers/cancers-12-00806/article_deploy/html/images/cancers-12-00806-g001.png)
32 * 32 * 4 * x = 196608, and so x turns out to be 48, which so happens to be 4 * 12 (4 walls * 12 floats per wall? Maybe not). To give a general idea of what I am working on, it is a small first-person dungeon crawler game, and a dungeon is exactly 32x32 cells, and each cell has 4 walls. This Common Lisp function, which simply computes four vertices of a wall's wireframe edges with extremely simple kindergarten-level arithmetic and a few 'case' tests appears to be responsible for dynamically allocating 196608 bytes per rendered frame SBCL's profiler tells me this is my most problematic function as far as consing goes.