Working on performance
This commit is contained in:
parent
b74a6c006e
commit
537dcf0db1
@ -71,22 +71,23 @@ Changed:
|
|||||||
|
|
||||||
- multi:newTStep now derives it's functionality from multi:newStep (Cut's down on code length a bit)
|
- 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:
|
### 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)
|
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:
|
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:
|
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
|
- [Issue](https://github.com/rayaman/multi/issues/29) where System threaded functions not up to date with threaded functions
|
||||||
|
|
||||||
ToDo:
|
ToDo:
|
||||||
|
|||||||
113
multi/init.lua
113
multi/init.lua
@ -201,6 +201,7 @@ end
|
|||||||
local ignoreconn = true
|
local ignoreconn = true
|
||||||
function multi:newConnection(protect,func,kill)
|
function multi:newConnection(protect,func,kill)
|
||||||
local c={}
|
local c={}
|
||||||
|
local call_funcs = {}
|
||||||
c.callback = func
|
c.callback = func
|
||||||
c.Parent=self
|
c.Parent=self
|
||||||
c.lock = false
|
c.lock = false
|
||||||
@ -245,8 +246,8 @@ function multi:newConnection(protect,func,kill)
|
|||||||
c.Type='connector'
|
c.Type='connector'
|
||||||
c.func={}
|
c.func={}
|
||||||
c.ID=0
|
c.ID=0
|
||||||
c.protect=protect or true
|
c.protect=protect or false
|
||||||
c.connections={}
|
local connections={}
|
||||||
c.FC=0
|
c.FC=0
|
||||||
function c:holdUT(n)
|
function c:holdUT(n)
|
||||||
local n=n or 0
|
local n=n or 0
|
||||||
@ -267,9 +268,9 @@ function multi:newConnection(protect,func,kill)
|
|||||||
c.HoldUT=c.holdUT
|
c.HoldUT=c.holdUT
|
||||||
function c:getConnection(name,ignore)
|
function c:getConnection(name,ignore)
|
||||||
if ignore then
|
if ignore then
|
||||||
return self.connections[name] or CRef
|
return connections[name] or CRef
|
||||||
else
|
else
|
||||||
return self.connections[name] or self
|
return connections[name] or self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function c:Lock()
|
function c:Lock()
|
||||||
@ -280,51 +281,58 @@ function multi:newConnection(protect,func,kill)
|
|||||||
c.lock = false
|
c.lock = false
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
function c:Fire(...)
|
if c.protect then
|
||||||
local ret={}
|
function c:Fire(...)
|
||||||
if self.lock then return end
|
if self.lock then return end
|
||||||
for i=#self.func,1,-1 do
|
for i=#call_funcs,1,-1 do
|
||||||
if self.protect then
|
if not call_funcs[i] then return end
|
||||||
if not self.func[i] then return end
|
pcall(call_funcs[i],...)
|
||||||
local temp={pcall(self.func[i][1],...)}
|
if kill then
|
||||||
if temp[1] then
|
table.remove(call_funcs,i)
|
||||||
table.remove(temp,1)
|
|
||||||
table.insert(ret,temp)
|
|
||||||
else
|
|
||||||
multi.print(temp[2])
|
|
||||||
end
|
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
|
||||||
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
|
end
|
||||||
function c:Bind(t)
|
function c:Bind(t)
|
||||||
local temp = self.func
|
local temp = call_funcs
|
||||||
self.func=t
|
call_funcs=t
|
||||||
return temp
|
return temp
|
||||||
end
|
end
|
||||||
function c:Remove()
|
function c:Remove()
|
||||||
local temp = self.func
|
local temp = call_funcs
|
||||||
self.func={}
|
call_funcs={}
|
||||||
return temp
|
return temp
|
||||||
end
|
end
|
||||||
local function conn_helper(self,func,name,num)
|
local function conn_helper(self,func,name,num)
|
||||||
self.ID=self.ID+1
|
self.ID=self.ID+1
|
||||||
if num then
|
if num then
|
||||||
table.insert(self.func,num,{func,self.ID})
|
table.insert(call_funcs,num,func)
|
||||||
else
|
else
|
||||||
table.insert(self.func,1,{func,self.ID})
|
table.insert(call_funcs,1,func)
|
||||||
end
|
end
|
||||||
local temp = {
|
local temp = {
|
||||||
Link=self.func,
|
|
||||||
func=func,
|
func=func,
|
||||||
Type="connector_link",
|
Type="connector_link",
|
||||||
ID=self.ID,
|
|
||||||
Parent=self,
|
Parent=self,
|
||||||
connect = function(s,...)
|
connect = function(s,...)
|
||||||
return self:connect(...)
|
return self:connect(...)
|
||||||
@ -350,29 +358,27 @@ function multi:newConnection(protect,func,kill)
|
|||||||
function temp:Fire(...)
|
function temp:Fire(...)
|
||||||
if self.Parent.lock then return end
|
if self.Parent.lock then return end
|
||||||
if self.Parent.protect then
|
if self.Parent.protect then
|
||||||
local t=pcall(self.func,...)
|
local t=pcall(call_funcs,...)
|
||||||
if t then
|
if t then
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return self.func(...)
|
return call_funcs(...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function temp:Destroy()
|
function temp:Destroy()
|
||||||
for i=1,#self.Link do
|
for i=1,#call_funcs do
|
||||||
if self.Link[i][2]~=nil then
|
if call_funcs[i]~=nil then
|
||||||
if self.Link[i][2]==self.ID then
|
if call_funcs[i]==self.func then
|
||||||
table.remove(self.Link,i)
|
table.remove(call_funcs,i)
|
||||||
self.remove=function() end
|
self.remove=function() end
|
||||||
self.Link=nil
|
|
||||||
self.ID=nil
|
|
||||||
multi.setType(temp,multi.DestroyedObj)
|
multi.setType(temp,multi.DestroyedObj)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if name then
|
if name then
|
||||||
self.connections[name]=temp
|
connections[name]=temp
|
||||||
end
|
end
|
||||||
if self.callback then
|
if self.callback then
|
||||||
self.callback(temp)
|
self.callback(temp)
|
||||||
@ -396,7 +402,6 @@ function multi:newConnection(protect,func,kill)
|
|||||||
else
|
else
|
||||||
return conn_helper(self,tab[1],tab[2],tab[3])
|
return conn_helper(self,tab[1],tab[2],tab[3])
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
c.Connect=c.connect
|
c.Connect=c.connect
|
||||||
c.GetConnection=c.getConnection
|
c.GetConnection=c.getConnection
|
||||||
@ -711,9 +716,14 @@ function multi:newLoop(func)
|
|||||||
self.OnLoop:Fire(self,clock()-start)
|
self.OnLoop:Fire(self,clock()-start)
|
||||||
end
|
end
|
||||||
c.OnLoop = self:newConnection()
|
c.OnLoop = self:newConnection()
|
||||||
|
function c:fastMode()
|
||||||
|
self.OnLoop:fastMode()
|
||||||
|
end
|
||||||
|
|
||||||
if func then
|
if func then
|
||||||
c.OnLoop(func)
|
c.OnLoop(func)
|
||||||
end
|
end
|
||||||
|
|
||||||
multi:create(c)
|
multi:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
@ -978,9 +988,9 @@ function thread.getRunningThread()
|
|||||||
local threads = globalThreads
|
local threads = globalThreads
|
||||||
local t = coroutine.running()
|
local t = coroutine.running()
|
||||||
if t then
|
if t then
|
||||||
for i,v in pairs(threads) do
|
for th,process in pairs(threads) do
|
||||||
if t==i.thread then
|
if t==th.thread then
|
||||||
return v
|
return th
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1204,16 +1214,16 @@ function thread:newFunctionBase(generator,holdme)
|
|||||||
return wait()
|
return wait()
|
||||||
end
|
end
|
||||||
local temp = {
|
local temp = {
|
||||||
OnStatus = multi:newConnection(),
|
OnStatus = multi:newConnection(true),
|
||||||
OnError = multi:newConnection(),
|
OnError = multi:newConnection(true),
|
||||||
OnReturn = multi:newConnection(),
|
OnReturn = multi:newConnection(true),
|
||||||
isTFunc = true,
|
isTFunc = true,
|
||||||
wait = wait,
|
wait = wait,
|
||||||
getReturns = function()
|
getReturns = function()
|
||||||
return unpack(rets)
|
return unpack(rets)
|
||||||
end,
|
end,
|
||||||
connect = function(f)
|
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.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)
|
t.OnError(function(self,err) if f then f(nil,err) else tempConn:Fire(nil,err) end end)
|
||||||
return tempConn
|
return tempConn
|
||||||
@ -2291,17 +2301,14 @@ function multi:benchMark(sec,p,pt)
|
|||||||
if pt then
|
if pt then
|
||||||
multi.print(pt.." "..c.." Steps in "..sec.." second(s)!")
|
multi.print(pt.." "..c.." Steps in "..sec.." second(s)!")
|
||||||
end
|
end
|
||||||
self.tt(sec,c)
|
self.OnBench:Fire(sec,c)
|
||||||
self:Destroy()
|
self:Destroy()
|
||||||
else
|
else
|
||||||
c=c+1
|
c=c+1
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
temp.OnBench = multi:newConnection()
|
||||||
temp:setPriority(p or 1)
|
temp:setPriority(p or 1)
|
||||||
function temp:OnBench(func)
|
|
||||||
self.tt=func
|
|
||||||
end
|
|
||||||
self.tt=function() end
|
|
||||||
return temp
|
return temp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
package.path = "?/init.lua;?.lua;" .. package.path
|
package.path = "?/init.lua;?.lua;" .. package.path
|
||||||
multi, thread = require("multi"):init() -- get it all and have it on all lanes
|
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
|
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
|
end
|
||||||
-- Step 1 get lanes
|
-- Step 1 get lanes
|
||||||
lanes = require("lanes").configure({allocator="protected",verbose_errors=""})
|
lanes = require("lanes").configure()
|
||||||
multi.SystemThreads = {}
|
multi.SystemThreads = {}
|
||||||
multi.isMainThread = true
|
multi.isMainThread = true
|
||||||
|
|
||||||
@ -47,12 +48,6 @@ end
|
|||||||
local __GlobalLinda = lanes.linda() -- handles global stuff
|
local __GlobalLinda = lanes.linda() -- handles global stuff
|
||||||
local __SleepingLinda = lanes.linda() -- handles sleeping stuff
|
local __SleepingLinda = lanes.linda() -- handles sleeping stuff
|
||||||
local __ConsoleLinda = lanes.linda() -- handles console 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 GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda,__SleepingLinda)
|
||||||
local count = 1
|
local count = 1
|
||||||
local started = false
|
local started = false
|
||||||
@ -65,6 +60,7 @@ function THREAD:newFunction(func,holdme)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function multi:newSystemThread(name, func, ...)
|
function multi:newSystemThread(name, func, ...)
|
||||||
|
print("Creating a thread")
|
||||||
multi.InitSystemThreadErrorHandler()
|
multi.InitSystemThreadErrorHandler()
|
||||||
local rand = math.random(1, 10000000)
|
local rand = math.random(1, 10000000)
|
||||||
local return_linda = lanes.linda()
|
local return_linda = lanes.linda()
|
||||||
@ -106,6 +102,7 @@ function multi:newSystemThread(name, func, ...)
|
|||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi.InitSystemThreadErrorHandler()
|
function multi.InitSystemThreadErrorHandler()
|
||||||
|
print("Thread Created!")
|
||||||
if started == true then
|
if started == true then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -113,7 +110,11 @@ function multi.InitSystemThreadErrorHandler()
|
|||||||
multi:newThread("SystemThreadScheduler",function()
|
multi:newThread("SystemThreadScheduler",function()
|
||||||
local threads = multi.SystemThreads
|
local threads = multi.SystemThreads
|
||||||
while true do
|
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
|
for i = #threads, 1, -1 do
|
||||||
local status = threads[i].thread.status
|
local status = threads[i].thread.status
|
||||||
local temp = threads[i]
|
local temp = threads[i]
|
||||||
@ -153,6 +154,7 @@ function multi.InitSystemThreadErrorHandler()
|
|||||||
print(...)
|
print(...)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
multi.print("Integrated Lanes!")
|
multi.print("Integrated Lanes!")
|
||||||
multi.integration = {} -- for module creators
|
multi.integration = {} -- for module creators
|
||||||
multi.integration.GLOBAL = GLOBAL
|
multi.integration.GLOBAL = GLOBAL
|
||||||
|
|||||||
33
test3.lua
33
test3.lua
@ -1,19 +1,28 @@
|
|||||||
package.path = "./?/init.lua;"..package.path
|
package.path = "./?/init.lua;"..package.path
|
||||||
local multi,thread = require("multi"):init()
|
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)
|
-- func = THREAD:newFunction(function(a,b,c)
|
||||||
if n > 0 then os.execute("ping -n " .. tonumber(n+1) .. " localhost > NUL") end
|
-- print("Hello Thread!",a,b,c)
|
||||||
end
|
-- return 1,2,3
|
||||||
|
-- end)
|
||||||
|
|
||||||
func = THREAD:newFunction(function(a,b,c)
|
-- func2 = THREAD:newFunction(function(a,b,c)
|
||||||
print("Hello Thread!",a,b,c)
|
-- print("Hello Thread2!",a,b,c)
|
||||||
return 1,2,3
|
-- 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)
|
end)
|
||||||
|
|
||||||
multi:newThread("Test thread",function()
|
|
||||||
handler = func(4,5,6)
|
|
||||||
thread.hold(handler.OnReturn)
|
|
||||||
print("Function Done",handler.getReturns())
|
|
||||||
end)
|
|
||||||
multi:mainloop()
|
multi:mainloop()
|
||||||
Loading…
x
Reference in New Issue
Block a user