A timing test for the table-style object creation. After that, I don’t know yet.
Here’s the test I wrote to time:
_:test("calling sequences", function()
function f_no_args()
end
function f_regular(a,b,c,d)
local a = a
local b = b
local c = c
local d = d
end
function f_table(parms)
local a = parms.a
local b = parms.b
local c = parms.c
local d = parms.d
end
local n = 16_500_000
local t0 = os.clock()
for i = 1, n do
end
local t_empty = os.clock()
for i = 1, n do
f_no_args()
end
local t_no_args = os.clock()
for i = 1, n do
f_regular(1,2,3,4)
end
local t_regular = os.clock()
for i = 1, n do
f_table{a=1, b=2, c= 3, d=4}
end
local t_table = os.clock()
local time_empty =t_empty - t0
local time_no_args = t_no_args - t_empty
local time_regular = t_regular - t_no_args
local time_table = t_table - t_regular
print("empty", time_empty)
print("no args", time_no_args)
print("regular", time_regular)
print("table", time_table, '\ntab/reg', time_table/time_regular)
print(n/time_table)
end)
As you can see, we iterate 16,500,000 times. And the results, in seconds:
Feature: timing tests
empty 0.07401849993038923
no args 0.1592389583820477
regular 0.21819420834071934
table 1.0065955416066572
tab/reg 4.613300917844787
16391886.62972206
I fiddled the number to get the table test to run in about one second. We can then conclude that, on my M1 Macbook Air, we can call over 16 million functions using the table format every second. Of course, who knows what that will mean in Second Life.
And we also see that the regular calling sequence is about one-fifth the speed of the table. Around 3/4 of that time is taken up just calling the function.
For our purposes here, we won’t be creating many objects using the table format, so its better expressiveness is well worth it in my view. In code that has to run fast, we’ll lean away from the tables and use regular calling sequences.
So that’s nice. What shall we do this morning?
I think we have the DriveWheel, ConnectingRod, and CouplingRod working. Maybe this morning we should draw some pictures. That will be interesting but not require too much brain power, I hope.
Let’s try to set up a test that draws, oh, four diagrams. Once that works, we should be able to enhance it as we add more objects. We’ll also have to sort out the to_svg
methods for our objects: they have not been run since the changes to calling sequence, vector, and angle, so the ones that exist will be wrong and I think Connecting Rod doesn’t even have a to_svg
method yet.
First the test.
_:test("draw structure", function()
svg._instances = {}
local steps = 4
local step = 1
for angle = 0,360,360/steps do
draw_structure(step, angle)
step += 1
end
print(Shape:draw())
end)
That would almost work if we had a draw_structure
function. I’ll put it inside the test for now. I suspect we’ll have a real object to put it in, someday.
Only a bit more hassle, and I have this picture:
The code for the picture isn’t too awful, though we’ll have some things to think about:
_:test("draw structure", function()
function draw_structure(step, angle)
local wheel = DriveWheel{x=12, y=2}
local dist = 2*math.pi*2*(angle/360)
wheel:move(dist)
wheel:to_svg()
end
svg._instances = {}
local rect = svg.Rect{x=0, y=0, width=640,
height=480, fill=0x191919}
local page = svg.Group({stroke_width=0.1}, function()
local steps = 8
local step = 1
for angle = 0,359,360/steps do
local g = svg.Group({}, function()
draw_structure(step, angle)
end)
g:translate(0, 5.5*(step-1) + 2)
step += 1
end
end)
page:scale(10,-10)
page:translate(0, -48)
print(svg.Shape:draw())
end)
Nothing to see here, just a call to a function test
, passing an anonymous function containing a function draw_structure
, and the anonymous function calls a function Group
passing another anonymous function function, and that anonymous function calls Group
again, passing yet another anonymous function, which finally calls draw_structure
.
Sometime, perhaps tomorrow, perhaps not, I’ll create a simpler version of this, which I’ll do by pulling out the anonymous functions, defining them first, and calling them by name. We’ll see what we think then.
Now, the truth is, I’m probably the only person who will ever do these SVG things, and the nested functions don’t trouble me.
And the picture’s not bad either, although I think I’d prefer to draw from the top down instead of bottom up. But that is just a matter of changing this translate:
g:translate(0, 5.5*(step-1) + 2)
If I were going to do a lot of these pictures, and it is possible that I will be, I’d try to package up the page layout ideas, like the translate above, separately from the diagram drawing ideas. But we don’t really want to get into page layout: it’s a jungle.
For today, I have a start at a drawing test that I can use to draw a whole linkage. I could do it right now, but I am tired and hungry.
Safe paths!