最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

淺析mc中漏斗卡頓的部分來源

2022-10-20 13:20 作者:Void0  | 我要投稿

mc中漏斗的卡頓是比較大的,很多人談漏斗色變,當(dāng)然這是完全沒必要的,因為生物的AI更卡一些(笑)然而漏斗的卡頓確實很大,其中比較大的一個部分歸結(jié)為尋找上方的物品實體以求吸取這一過程,但是其實還有一部分的卡頓來源于屎山代碼,這一部分長時間不被記載,比較不為人知?,F(xiàn)在我們來看一下:

首先從一個方法講起:net.minecraft.world#World.updateComparators

這是一個毫無槽點的方法,用于更新一個方塊附近的比較器。這用于讓比較器能夠檢測容器。那么我們看看它在什么時候可以被調(diào)用。下面是net.minecraft.block.entity#BlockEntity中的兩段代碼:

我們看到,markDirty() 方法用于標(biāo)注某個位置方塊實體的信息已被更改,保存世界的時候需要注意。它還會調(diào)用 world.updateComparators() 以更新附近的比較器,畢竟方塊實體的一大類是容器,當(dāng)容器內(nèi)容被更改時,更新一下比較器是必要的,至此,一切正常。

然后很快你就會發(fā)現(xiàn)事情變得非常的不正常……

我們現(xiàn)在看一下漏斗邏輯的控制,這部分代碼全都在net.minecraft.block.entity#HopperBlockEntity里面。以下是漏斗執(zhí)行一次吸取操作的代碼:

注釋為編者所加

我們看到漏斗會優(yōu)先檢測上方有沒有容器,有的話就對容器的每一格執(zhí)行一次遍歷,如果能夠吸取這一格就吸取掉,然后結(jié)束遍歷,沒有的話就試著吸取物品實體。

問題就出在從容器吸取這一過程,我們來看代碼。

注釋為編者所加,下面注釋掉的代碼,是編者給出的更為優(yōu)化的解法

從這里,我們就可以看到麻將的迷惑操作了。我們可以從中看到主要的邏輯(以下并非是嚴(yán)格的源代碼邏輯,是經(jīng)過編者簡化的等價的邏輯):

  • 把要吸取的容器的那一格取出來,如果非空進(jìn)行接下來的操作

  • 將容器的這一格內(nèi)容復(fù)制一份,然后在原來的容器中,將這一格的內(nèi)容物數(shù)量 -1

  • 試著將減掉的 1 個內(nèi)容物放到漏斗里面

  • 如果放進(jìn)去了,那么很好,進(jìn)程結(jié)束

  • 如果沒放進(jìn)去,就把剛剛復(fù)制的內(nèi)容替代容器那一格的內(nèi)容,相當(dāng)于撤銷剛剛 -1 的操作

這個邏輯雖然很奇怪,但是好像也能實現(xiàn)目的,貌似沒問題,但是結(jié)合剛才說的比較器更新,問題就大了。

這個過程中,假設(shè)吸取失敗,那么會先減掉容器的 1 個內(nèi)容物,然后再復(fù)原,這兩個過程都會更改容器的內(nèi)容,理應(yīng)調(diào)用 markDirty() 方法,從而引發(fā)比較器更新。事實上它確實會調(diào)用,比如我們以箱子為例,它的物品欄在 net.minecraft.block.entity#LootableContainerBlockEntity 中實現(xiàn),我們看看漏斗吸取過程中調(diào)用的兩個方法,一個是 removeStack(),一個是 setStack(),它們確實都調(diào)用了 markDirty():

將要被反復(fù)調(diào)用而面露難色的兩方法

于是,漏斗每次對一格失敗的吸取,會產(chǎn)生 2 次比較器更新,這問題貌似也不太大,但是別忘了每次吸取,漏斗會對上面的容器的每一格進(jìn)行遍歷!

現(xiàn)在考慮這樣一個情形,上面有一個塞滿東西了的大箱子,下面接了一個漏斗,漏斗里面的物品類型和箱子的內(nèi)容不匹配,因此吸不進(jìn)任何東西,并且漏斗不是滿的(所以會嘗試吸東西)。那么漏斗每次嘗試吸取一格的操作,都會是失敗的。于是每一格都會被遍歷一遍,嘗試吸取一遍——

這個過程中,上面產(chǎn)生 2 次沒必要的比較器更新的 extract 方法,將被調(diào)用 54 遍。

這會產(chǎn)生 108 次比較器更新?。。。。。?/strong>

也無怪乎漏斗的卡頓較大了,這樣的卡頓當(dāng)然是顯著的,都能拿來做卡服機(jī)了(逃)

不愧是你啊麻將

啊↑啊↓我要把麻將撕成兩半!

淺析mc中漏斗卡頓的部分來源的評論 (共 條)

分享到微博請遵守國家法律
宜川县| 宁河县| 南开区| 德化县| 蒙山县| 老河口市| 荆门市| 安阳县| 桐城市| 白城市| 交口县| 台东县| 疏附县| 万州区| 山东省| 西乌珠穆沁旗| 营山县| 凤凰县| 嵊州市| 通道| 井研县| 瑞昌市| 东辽县| 新疆| 南京市| 沧源| 珠海市| 鞍山市| 宁都县| 临夏县| 德化县| 湖南省| 资源县| 保定市| 通许县| 乌恰县| 海原县| 达日县| 天台县| 太仓市| 清远市|