Working on performance

This commit is contained in:
Ryan Ward 2022-01-04 18:01:02 -05:00
parent b74a6c006e
commit 537dcf0db1
4 changed files with 96 additions and 77 deletions

View File

@ -71,22 +71,23 @@ Changed:
- multi:newTStep now derives it's functionality from multi:newStep (Cut's down on code length a bit)
-
- Fixed the getTaskDetails to handle the new format for threads
### Developer Note:
Connections are some of the most complex objects that this library has outside of some of the system threaded stuff. I tend to add features to connection objects quite often. Just last update connections can be "added" together creating a temp connection that only triggers when all of the added connections got triggered as well. Thinking about the possibilities this could give developers using the library I had to changed the base classes to use connections.
Connections are one of the most complex objects that this library has outside of some of the system threaded stuff. I tend to add features to connection objects quite often. Just last update connections can be "added" together creating a temp connection that only triggers when all of the added connections got triggered as well. Thinking about the possibilities this could give developers using the library I had to changed the base classes to use connections.
The best part about this is that connections allow for greater control over an object's events. You can add and remove events that have been connected to as well as a lot of other things. Reference the documentation [here](./Documentation.md#non-actor-connections)
Removed:
---
Nothing
- Calling Fire on a connection no longer returns anything! Now that internal features use connections, I noticed how slow connections are and have increased their speed quite a bit. From 50,000 Steps per seconds to almost 7 Million. All other features should work just fine. Only returning values has been removed
Fixed:
---
- [Issue](https://github.com/rayaman/multi/issues/30) with Lanes crashing the lua state. Fixed it with pcall
- [Issue](https://github.com/rayaman/multi/issues/30) with Lanes crashing the lua state. Issue seems to be related to my filesystem
- [Issue](https://github.com/rayaman/multi/issues/29) where System threaded functions not up to date with threaded functions
ToDo:

View File

@ -201,6 +201,7 @@ end
local ignoreconn = true
function multi:newConnection(protect,func,kill)
local c={}
local call_funcs = {}
c.callback = func
c.Parent=self
c.lock = false
@ -245,8 +246,8 @@ function multi:newConnection(protect,func,kill)
c.Type='connector'
c.func={}
c.ID=0
c.protect=protect or true
c.connections={}
c.protect=protect or false
local connections={}
c.FC=0
function c:holdUT(n)
local n=n or 0
@ -267,9 +268,9 @@ function multi:newConnection(protect,func,kill)
c.HoldUT=c.holdUT
function c:getConnection(name,ignore)
if ignore then
return self.connections[name] or CRef
return connections[name] or CRef
else
return self.connections[name] or self
return connections[name] or self
end
end
function c:Lock()
@ -280,51 +281,58 @@ function multi:newConnection(protect,func,kill)
c.lock = false
return self
end
function c:Fire(...)
local ret={}
if self.lock then return end
for i=#self.func,1,-1 do
if self.protect then
if not self.func[i] then return end
local temp={pcall(self.func[i][1],...)}
if temp[1] then
table.remove(temp,1)
table.insert(ret,temp)
else
multi.print(temp[2])
if c.protect then
function c:Fire(...)
if self.lock then return end
for i=#call_funcs,1,-1 do
if not call_funcs[i] then return end
pcall(call_funcs[i],...)
if kill then
table.remove(call_funcs,i)
end
else
if not self.func[i] then return end
table.insert(ret,{self.func[i][1](...)})
end
if kill then
table.remove(self.func,i)
end
end
return ret
else
function c:Fire(...)
for i=#call_funcs,1,-1 do
call_funcs[i](...)
if kill then
table.remove(call_funcs,i)
end
end
end
end
local fast = {}
function c:fastMode()
function self:Fire(...)
for i=1,#fast do
fast[i](...)
end
end
function self:connect(func)
table.insert(fast,func)
end
end
function c:Bind(t)
local temp = self.func
self.func=t
local temp = call_funcs
call_funcs=t
return temp
end
function c:Remove()
local temp = self.func
self.func={}
local temp = call_funcs
call_funcs={}
return temp
end
local function conn_helper(self,func,name,num)
self.ID=self.ID+1
if num then
table.insert(self.func,num,{func,self.ID})
table.insert(call_funcs,num,func)
else
table.insert(self.func,1,{func,self.ID})
table.insert(call_funcs,1,func)
end
local temp = {
Link=self.func,
func=func,
Type="connector_link",
ID=self.ID,
Parent=self,
connect = function(s,...)
return self:connect(...)
@ -350,29 +358,27 @@ function multi:newConnection(protect,func,kill)
function temp:Fire(...)
if self.Parent.lock then return end
if self.Parent.protect then
local t=pcall(self.func,...)
local t=pcall(call_funcs,...)
if t then
return t
end
else
return self.func(...)
return call_funcs(...)
end
end
function temp:Destroy()
for i=1,#self.Link do
if self.Link[i][2]~=nil then
if self.Link[i][2]==self.ID then
table.remove(self.Link,i)
for i=1,#call_funcs do
if call_funcs[i]~=nil then
if call_funcs[i]==self.func then
table.remove(call_funcs,i)
self.remove=function() end
self.Link=nil
self.ID=nil
multi.setType(temp,multi.DestroyedObj)
end
end
end
end
if name then
self.connections[name]=temp
connections[name]=temp
end
if self.callback then
self.callback(temp)
@ -396,7 +402,6 @@ function multi:newConnection(protect,func,kill)
else
return conn_helper(self,tab[1],tab[2],tab[3])
end
end
c.Connect=c.connect
c.GetConnection=c.getConnection
@ -711,9 +716,14 @@ function multi:newLoop(func)
self.OnLoop:Fire(self,clock()-start)
end
c.OnLoop = self:newConnection()
function c:fastMode()
self.OnLoop:fastMode()
end
if func then
c.OnLoop(func)
end
multi:create(c)
return c
end
@ -978,9 +988,9 @@ function thread.getRunningThread()
local threads = globalThreads
local t = coroutine.running()
if t then
for i,v in pairs(threads) do
if t==i.thread then
return v
for th,process in pairs(threads) do
if t==th.thread then
return th
end
end
end
@ -1204,16 +1214,16 @@ function thread:newFunctionBase(generator,holdme)
return wait()
end
local temp = {
OnStatus = multi:newConnection(),
OnError = multi:newConnection(),
OnReturn = multi:newConnection(),
OnStatus = multi:newConnection(true),
OnError = multi:newConnection(true),
OnReturn = multi:newConnection(true),
isTFunc = true,
wait = wait,
getReturns = function()
return unpack(rets)
end,
connect = function(f)
local tempConn = multi:newConnection()
local tempConn = multi:newConnection(true)
t.OnDeath(function(self,status,...) if f then f(...) else tempConn:Fire(...) end end)
t.OnError(function(self,err) if f then f(nil,err) else tempConn:Fire(nil,err) end end)
return tempConn
@ -2291,17 +2301,14 @@ function multi:benchMark(sec,p,pt)
if pt then
multi.print(pt.." "..c.." Steps in "..sec.." second(s)!")
end
self.tt(sec,c)
self.OnBench:Fire(sec,c)
self:Destroy()
else
c=c+1
end
end)
temp.OnBench = multi:newConnection()
temp:setPriority(p or 1)
function temp:OnBench(func)
self.tt=func
end
self.tt=function() end
return temp
end

View File

@ -21,6 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
package.path = "?/init.lua;?.lua;" .. package.path
multi, thread = require("multi"):init() -- get it all and have it on all lanes
if multi.integration then -- This allows us to call the lanes manager from supporting modules without a hassle
@ -31,7 +32,7 @@ if multi.integration then -- This allows us to call the lanes manager from suppo
}
end
-- Step 1 get lanes
lanes = require("lanes").configure({allocator="protected",verbose_errors=""})
lanes = require("lanes").configure()
multi.SystemThreads = {}
multi.isMainThread = true
@ -47,12 +48,6 @@ end
local __GlobalLinda = lanes.linda() -- handles global stuff
local __SleepingLinda = lanes.linda() -- handles sleeping stuff
local __ConsoleLinda = lanes.linda() -- handles console stuff
multi:newLoop(function()
local _,data = __ConsoleLinda:receive(0, "Q")
if data then
print(unpack(data))
end
end)
local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda,__SleepingLinda)
local count = 1
local started = false
@ -65,6 +60,7 @@ function THREAD:newFunction(func,holdme)
end
function multi:newSystemThread(name, func, ...)
print("Creating a thread")
multi.InitSystemThreadErrorHandler()
local rand = math.random(1, 10000000)
local return_linda = lanes.linda()
@ -106,6 +102,7 @@ function multi:newSystemThread(name, func, ...)
return c
end
function multi.InitSystemThreadErrorHandler()
print("Thread Created!")
if started == true then
return
end
@ -113,7 +110,11 @@ function multi.InitSystemThreadErrorHandler()
multi:newThread("SystemThreadScheduler",function()
local threads = multi.SystemThreads
while true do
thread.sleep(.01) -- switching states often takes a huge hit on performance. half a second to tell me there is an error is good enough.
thread.sleep(.005) -- switching states often takes a huge hit on performance. half a second to tell me there is an error is good enough.
local _,data = __ConsoleLinda:receive(0, "Q")
if data then
print(unpack(data))
end
for i = #threads, 1, -1 do
local status = threads[i].thread.status
local temp = threads[i]
@ -153,6 +154,7 @@ function multi.InitSystemThreadErrorHandler()
print(...)
end)
end
multi.print("Integrated Lanes!")
multi.integration = {} -- for module creators
multi.integration.GLOBAL = GLOBAL

View File

@ -1,19 +1,28 @@
package.path = "./?/init.lua;"..package.path
local multi,thread = require("multi"):init()
local GLOBAL,THREAD = require("multi.integration.threading"):init()
local GLOBAL,THREAD = require("multi.integration.lanesManager"):init()
function sleep(n)
if n > 0 then os.execute("ping -n " .. tonumber(n+1) .. " localhost > NUL") end
end
-- func = THREAD:newFunction(function(a,b,c)
-- print("Hello Thread!",a,b,c)
-- return 1,2,3
-- end)
func = THREAD:newFunction(function(a,b,c)
print("Hello Thread!",a,b,c)
return 1,2,3
-- func2 = THREAD:newFunction(function(a,b,c)
-- print("Hello Thread2!",a,b,c)
-- THREAD.sleep(1)
-- return 10,11,12
-- end)
-- multi:newThread("Test thread",function()
-- handler = func(4,5,6)
-- handler2 = func2(7,8,9)
-- thread.hold(handler.OnReturn + handler2.OnReturn)
-- print("Function Done",handler.getReturns())
-- print("Function Done",handler2.getReturns())
-- end)
multi:benchMark(1):OnBench(function(sec,steps)
print("Steps:",steps)
os.exit()
end)
multi:newThread("Test thread",function()
handler = func(4,5,6)
thread.hold(handler.OnReturn)
print("Function Done",handler.getReturns())
end)
multi:mainloop()