Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node:getChildren()性能问题 #2068

Closed
qq461787436 opened this issue Aug 3, 2024 · 6 comments
Closed

Node:getChildren()性能问题 #2068

qq461787436 opened this issue Aug 3, 2024 · 6 comments
Labels

Comments

@qq461787436
Copy link

qq461787436 commented Aug 3, 2024

  • axmol version:axmol lua 2.1.4
  • devices test on:mac os 14.5
  • developing environments
    • Xcode version: 15.4+
  • Steps to Reproduce:
    开多个计时器调用 Node:getChildren() 非常消耗性能,cocos2d没这么差,不知道啥原因,特来请教

试例代码如下:

for _playindex=1, 5, 1 do
	local _Node = ccui.Layout:create()
	_Node:setContentSize(cc.size(50, 200))
	_Node:setPosition(cc.p(55*_playindex,0))
	_Node:setAnchorPoint(CWPointMake(0,0))
	self:addChild(_Node)

	for _i=1, 10, 1 do
		local _FileName = "DefaultRes_Icon.png"
		local _GradeSp = cc.Sprite:createWithSpriteFrameName(_FileName)
		_Node:addChild(_GradeSp)
		_GradeSp:setTag(_i)
		_GradeSp:setPosition(CWPointMake(25, #_Node:getChildren()*25))
	end

	local _ASpeed = 100
	local _CurSpeed = 0
	local _MaxSpeed = 200
	local _GradeHight = 100/3
	local _StopActIndex = 0
	local _LostTime = 0
	cc.Director:getInstance():getScheduler():scheduleScriptFunc(function(_dt)
		_LostTime = _LostTime + _dt

		local _CurNodePtY = _Node:getPositionY()
		_CurNodePtY = _CurNodePtY-_dt*_CurSpeed
		_Node:setPositionY(_CurNodePtY)

		_CurSpeed = _CurSpeed+_dt*_ASpeed
		if _CurSpeed > _MaxSpeed then
			_CurSpeed = _MaxSpeed
		end

		if math.abs(_CurNodePtY)>_GradeHight then
			local _Children = _Node:getChildren()
			_Node:setPositionY(0)
		end
	end, 0, false)
end

QQ20240803-114830

程序满帧率被设置成60
运行上面代码帧率在50左右,注释掉 local _Children = _Node:getChildren() 帧率可以保持在60
有没有知道如何优化的

@rh101
Copy link
Contributor

rh101 commented Aug 3, 2024

Have you tried running the Time Profiler Instrument in Xcode to find out what section of code is causing the performance issue?

@qq461787436
Copy link
Author

I tried runing it, the result is shown in the figure
QQ20240805-160825

@rh101
Copy link
Contributor

rh101 commented Aug 5, 2024

I'm not sure what that LUA method does, but perhaps someone else with knowledge can help with this.

A possibly work-around is if you keep track of the children outside of that scheduled method, you wouldn't need to call _Node:getChildren() on every loop.

Also, which version of Cocos2d-x are you comparing Axmol to? v3.17, or v4?

Other than that, I'm curious about this section of code (check the comment please):

	cc.Director:getInstance():getScheduler():scheduleScriptFunc(function(_dt)
		_LostTime = _LostTime + _dt

		local _CurNodePtY = _Node:getPositionY()
		_CurNodePtY = _CurNodePtY-_dt*_CurSpeed
		_Node:setPositionY(_CurNodePtY)  --> Y is set here, but then it is also set below again to 0 if the condition is met

		_CurSpeed = _CurSpeed+_dt*_ASpeed
		if _CurSpeed > _MaxSpeed then
			_CurSpeed = _MaxSpeed
		end

		if math.abs(_CurNodePtY)>_GradeHight then
			local _Children = _Node:getChildren()
			_Node:setPositionY(0)
		end
	end, 0, false)

Would this be better:

	cc.Director:getInstance():getScheduler():scheduleScriptFunc(function(_dt)
		_LostTime = _LostTime + _dt

		local _CurNodePtY = _Node:getPositionY()
		_CurNodePtY = _CurNodePtY-_dt*_CurSpeed

		_CurSpeed = _CurSpeed+_dt*_ASpeed
		if _CurSpeed > _MaxSpeed then
			_CurSpeed = _MaxSpeed
		end

		if math.abs(_CurNodePtY)>_GradeHight then
                        local _Children = _Node:getChildren()
			_Node:setPositionY(0)
                else
                        _Node:setPositionY(_CurNodePtY) 
		end
	end, 0, false)

@qq461787436
Copy link
Author

qq461787436 commented Aug 5, 2024

用于测试,写的有点不严谨
我还测试了下lua对table的循环遍历,性能上也很差,貌似都消耗在static lu_mem propagatemark (global_State *g) 这个函数里
测试代码如下(直接复制就可以运行):

function PrintObj(_value)
    local tv = ""
    local xn = 0

    local function tvlinet(xn)
        for i=1, xn do
            tv = tv.."    "
        end
    end

    local function LogString(lv)
        local _lt = type(lv)

        if lv == nil then
            return "nil"
        elseif _lt == "string" then
            return string.format("\"%s\"", lv)
        elseif _lt == "number" then
            return string.format("[%s]", tostring(lv))
        elseif _lt == "boolean" then
            return string.format("<%s>", lv)
        else
            return string.format("<%s>", _lt)
        end
    end

    local function printTab(k,v)
        if type(v) == "table" then
            --输出table键值
            tvlinet(xn)
            tv = tv..LogString(k)..":\n"
            
            tvlinet(xn)
            tv = tv.."{\n"
            xn = xn + 1
            --输出下一个键值
            for _vk, _vv in pairs(v) do
                printTab(_vk, _vv)
            end
            --输出结束符号
            xn = xn - 1
            tvlinet(xn)
            tv = tv.."}\n"
        else
            --输出值
            tvlinet(xn)
            tv = tv..LogString(k)..":"..LogString(v).."\n" 
        end
    end

   for i=1, #_value do
        local _LogV = _value[i]

        if type(_LogV) == "table" then 
            xn = xn + 1
            tv = tv.."\n{\n"
            for _vk, _vv in pairs(_LogV) do
                printTab(_vk, _vv)
            end
            tv = tv.."}\n"
        else
            tv = tv..LogString(_LogV)
        end
    end

    print(tv)
end

local _table = {
	test1=0,
	test2=false,
	test3=-123,
	test4=123,
	test5=123.123,
	test6=-123.123,
	test7=77.77,
	test8=-77.77,
	testmap={
		name="sdfsf",
		test=23.234,
		test2={1,2,4,6,7,8,345,56.77,{1,2,3,4}},
		test3="asdfkjsdlkfgj",
		test4={test1={234234,333}, 2,4,5,6},
		test5={123,23434, test1={234234,333}, 2,4,5,6},
		test6={123,23434,2,4,5,6,test1={234234,333}},
	}
}

for _playindex=1, 10, 1 do
	Obj({_table})
end

axmol lua 2.1.4 消耗了2.92s,用cocos2d lua 4.0版本消耗0.07s,这两个运行环境是一样但差距有点大呀,能力有限有没有大神看看哪里出问题了?

@halx99
Copy link
Collaborator

halx99 commented Aug 5, 2024

#332, maybe GC 模式设置错误,请检查下

@qq461787436
Copy link
Author

以前的项目修改了GC模式,现在项目迁移,没发现这个还能导致性能问题
在启动lua的时候设置
collectgarbage("setpause", 100)
collectgarbage("setstepmul", 5000)
去掉,问题一下子解决了
非常感谢

@axmolengine axmolengine locked and limited conversation to collaborators Aug 5, 2024
@halx99 halx99 converted this issue into discussion #2074 Aug 5, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Projects
None yet
Development

No branches or pull requests

3 participants