Skip to content
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

Optimize the performance of SHRINK which use auto wrap. #5914

Merged
merged 4 commits into from Dec 26, 2019

Conversation

caryliu1999
Copy link
Contributor

@caryliu1999 caryliu1999 commented Dec 17, 2019

Re: https://github.com/cocos-creator/2d-tasks/issues/1405

Changes:
优化使用自动换行时的SHRINK性能。

@holycanvas
Copy link
Contributor

@holycanvas holycanvas commented Dec 19, 2019

这是为了少调measureText做的优化么

@caryliu1999
Copy link
Contributor Author

@caryliu1999 caryliu1999 commented Dec 19, 2019

这是为了少调measureText做的优化么

是,增加的 Cache 是为了少调用 measureText,Shrink 那里的修改是为了减少匹配计算的次数, issue里有测试说明。

if (lambda()) {
right = mid - 1;
} else {
left = mid;
Copy link
Member

@jareguo jareguo Dec 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为什么不是 mid + 1

Copy link
Contributor Author

@caryliu1999 caryliu1999 Dec 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为什么不是 mid + 1

因为 mid 有可能是最终符合要求的size,所以要保留下来。

cocos2d/core/utils/text-utils.js Outdated Show resolved Hide resolved
cocos2d/core/utils/text-utils.js Outdated Show resolved Hide resolved
cocos2d/core/utils/text-utils.js Outdated Show resolved Hide resolved
cocos2d/core/utils/text-utils.js Outdated Show resolved Hide resolved
@jareguo
Copy link
Member

@jareguo jareguo commented Dec 19, 2019

另外我还有一个疑问是,LRU 缓存和二分查找似乎有点冲突的……

  1. 二分查找过程中,可能有大量的无效缓存生成,实际上只有最后一次缓存才是有用的?因为相同的字符串通常不会用在不同宽度的文本框中,一般都是一模一样的 UI,所以最终缓存的字号只需要一个就好。
  2. 二分查找是针对无 LRU 的情况下的最优解。如果有缓存,似乎二分查找就应该和缓存结合起来进行匹配。先查找指定字符串 + 字体是否在缓存中,在的话,看一下现有的缓存字号有哪些,然后直接取最接近的两个字号做为二分查找的 left 和 right。当然,复杂度可能会高一点?仅供参考吧

@caryliu1999
Copy link
Contributor Author

@caryliu1999 caryliu1999 commented Dec 20, 2019

另外我还有一个疑问是,LRU 缓存和二分查找似乎有点冲突的……

  1. 二分查找过程中,可能有大量的无效缓存生成,实际上只有最后一次缓存才是有用的?因为相同的字符串通常不会用在不同宽度的文本框中,一般都是一模一样的 UI,所以最终缓存的字号只需要一个就好。
  2. 二分查找是针对无 LRU 的情况下的最优解。如果有缓存,似乎二分查找就应该和缓存结合起来进行匹配。先查找指定字符串 + 字体是否在缓存中,在的话,看一下现有的缓存字号有哪些,然后直接取最接近的两个字号做为二分查找的 left 和 right。当然,复杂度可能会高一点?仅供参考吧

这里LRU缓存对于SHRINK的频繁查询来说确实会因为太多的无效字符查询导致缓存空间被占用,但是修改LRU缓存为双向链表的方式,降低查询跟记录时的性能消耗。缓存应该不会带来太多负面影响,对于非SHRINK模式的文本也会有一定改善。

至于SHRINK这种频繁操作跟LRU的冲突,如果通过缓存反向去定位SHRINK的size可能不是很合适了,文本内容可能从多变少,也可能是从少变多,不会比二分快什么。想解决这个问题,LRU可以分成hot跟非hot两个缓存来避免,只有达到一定查询次数之后才从非hot转移到hot部分,查询的时候优先从hot查询,再找非hot区域,不过非hot区域的管理是个问题,会带来一些消耗,这种方式能否接受?

@jareguo
Copy link
Member

@jareguo jareguo commented Dec 23, 2019

想解决这个问题,LRU可以分成hot跟非hot两个缓存来避免,只有达到一定查询次数之后才从非hot转移到hot部分,查询的时候优先从hot查询,再找非hot区域,不过非hot区域的管理是个问题,会带来一些消耗,这种方式能否接受?

这确实是一个办法。不过有点复杂了,毕竟不是 C++ 引擎,还是算了吧

cocos2d/core/utils/text-utils.js Outdated Show resolved Hide resolved
cocos2d/core/utils/text-utils.js Show resolved Hide resolved
cocos2d/core/utils/text-utils.js Outdated Show resolved Hide resolved
@jareguo jareguo merged commit afd8a4b into cocos:v2.3.0 Dec 26, 2019
1 check passed
@caryliu1999 caryliu1999 deleted the v2.3.0-shrink branch Jun 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants