处理动画工具数据存储的最有效/最快捷方式

时间:2016-04-22 20:37:28

标签: c# animation optimization unity3d collections

如果我有一堆可能是非线性但有序的值:1,3,8,12和我添加了一个新的,比如5什么是最好的集合类型(速度超过其他任何东西)将存储它在3到8之间并且给我索引以便我可以直接检查该值和前面的值。它是一个动画系统,我正在存储关键帧,我需要知道前后的内容,以便我可以正确地插值这些值

目前我正在使用散列表(dicitonary),密钥是关键帧存储在的帧号,其值是我想要的位置。

所以使用这种方法,它对于在进行更改时更新关键帧非常有用,但是在动画制作时,如果我将soem数据放在5中,则找到3和8让我遍历整个列表以找出索引。当前条目然后存储前一个并迭代到下一个..(更不用说每次我在字典中添加一些内容时,需要按键对其进行排序才能使其工作)。

只是寻找一些建议来解决这个相当开放的问题。

要深入了解此动画工具的当前结构:

我有一个名为时间轴的组件,这是KeyframeProperties记录的内容。因此,在一个关键帧属性中,你会调用record(),它会询问它所连接的时间线,如果它可以记录到当前插槽中,如果可以的话,它会返回索引所在的索引。记录了关键帧,然后关键帧属性将该索引存储到当前具有动画制作者当前数据的字典中。当您选择播放动画时,您调用timeline.play()函数,它将处理迭代所有连接的属性并调用keyframeproperty.advanceframe(int frame#)。这就是为什么我需要上一帧和下一帧,因为不知道这一点,当帧#被传入时,没有办法知道动画的下一个插值目的地应该在哪里..

示例:传入4并且属性中最接近的两个关键帧位于3和7,动画应将起始位置设置为第3帧数据,然后插入到第7个0.25(1 /(7-3) )= 0.25)

2 个答案:

答案 0 :(得分:2)

我认为.NET中没有任何集合/容器可以返回插入项的索引。至少有序的那些不提供这种能力。

你的问题实际上比表面看起来更复杂。因为,就我的问题标签而言,您可以将Unity与您的解决方案一起使用,该解决方案使用了一个针对.NET 3.5配置文件的相当古老的Mono实现。此外,由于Unity能够使用IL2CPP将C#代码转换为C ++(取决于您所针对的平台),您甚至可能需要考虑C ++编译器如何处理您的代码,无论它是否会对您的代码进行矢量化。所以,很难给你一个直接的答案,但我会试一试......

如果您的数据集较小(我会说少于几千个项目,这是一个相对数量,具体取决于您的目标平台),那么您几乎可以使用您选择的任何收集/容器,它不会很大的区别。如果是这种情况,那么我会选择LinkedList,因为它允许您通过一次搜索操作同时拥有您要查找的项目及其邻居(列表中的上一个和下一个项目)。在您的情况下,如果您对包含关键帧5的LinkedListNode有引用,则可以使用LinkedListNode对象的Previous和Next属性来检查上一个和下一个关键帧的位置。这很方便......

如果你有一个大数据集;首先,对你来说更重要的是插入速度还是检索速度?不幸的是,他们采取相反的方式,所以你必须在那里做出选择。如果检索速度是你喜欢的,那么忘记LinkedList类,它对于迭代大量数据来说太慢了。但是,如果您喜欢插入速度,那么LinkedList也是一个不错的选择,因为每次向列表添加值时都不必对所有数据进行排序。你可以在你想要的位置插入一个项目,它所要做的就是在这里和那里改变几个指针。问题是您必须告诉它要将项目添加到的位置。这意味着,您仍然需要执行搜索以找到要插入项目的位置,这将是昂贵的,但仍然不如使用成千上万的项目那么糟糕。

如果您要针对IL2CPP,那么我将忘记上述所有内容并使用一个简单的数组并自行实现所有搜索,插入,排序,数组大小调整操作。因为数组上的搜索操作很可能被C ++编译器矢量化,这将为大型数据集提供极大的速度提升。

答案 1 :(得分:2)

就速度而言,数组与列表或词典之间没有区别,除非您正在处理大量数据并对其进行密集处理(例如每帧100次)。所以,不要担心,只要使用任何使你更容易的事情,不要做Premature Optimization