【问题标题】:Extending/Merging VB Arrays扩展/合并 VB 数组
【发布时间】:2010-09-09 19:04:16
【问题描述】:

我有一个带有公共字节数组的类。让我们说它

Public myBuff as byte()

类中的事件获取字节数组中的数据块。我如何告诉事件代码将 get 块放在最后?让我们说

Private Sub GetChunk
  Dim chunk as byte
  '... get stuff in chunk
  Me.myBuff += chunk '(stick chunk on end of public array)
End sub

或者我完全没有抓住重点?

【问题讨论】:

    标签: arrays vba concatenation


    【解决方案1】:

    如果我没记错的话,在 vb 中你想用preserve来redim来增长一个数组。

    【讨论】:

    • 但是你能用一个定义为类中公共项目的数组来做到这一点吗?即你可以一起使用保留词 piblic 和 redim 吗?
    • ReDim Preserve yourArray(newSize)
    【解决方案2】:

    您将不断使用 ReDim 关键字,这非常效率低下。

    您使用的是 .Net 吗?如果是这样,请考虑改用 System.Collections.Generic.List(Of Byte)。你可以使用它的 .AddRange() 方法来追加你的字节,如果你真的需要一个数组,它的 .ToArray() 方法可以取出一个数组。

    【讨论】:

    • List(Of Byte) 似乎有一些大小限制。它不能超过某个阈值,而 ArrayList 可以。
    • List(Of Byte) 的 Count 和 Capacity 属性是 Int32s,与 ArrayList 相同。 ArrayList 会将您放入其中的每个字节装箱,从而增加大量 GC 和内存开销。也许您遇到了虚拟内存碎片问题?很少能获得 2GB 的免费 VM 块。
    • 我不这么认为。我是在 x64 盒子上做的。在我杀死它之前,arraylist 飙升到大约 3.5gb,而 List 大约 900mb。
    【解决方案3】:

    您的问题似乎不是很清楚。您可能不应该公开字节数组。它可能应该是私有的,并且您应该提供一组公共函数,允许该类的用户对数组执行操作。

    【讨论】:

      【解决方案4】:

      我认为您可能正在寻找数组以外的东西。如果你试图频繁地逐步扩展数据量,你应该使用动态数据结构,例如ArrayList。这有一个Add 方法,可以将特定对象或值添加到数组中,而不用担心空间。它还有一个漂亮的 ToArray() 方法供您使用。

      如果您出于特定原因(我猜是性能)尝试使用数组,请使用ReDim Preserve array(newSize)

      【讨论】:

        【解决方案5】:

        如果数组很小,并且很少添加新数据,一个简单的方法是:

        public BufferSize as long 'or you can just use Ubound(mybuff), I prefer a tracker var tho
        public MyBuff
        
        private sub GetChunk()
        dim chunk as byte
        'get stuff
        BufferSize=BufferSize+1
        
        redim preserve MyBuff(buffersize)
        mybuff(buffersize) = chunk
        end sub
        

        如果块是一个字节数组,它看起来更像:

        buffersize=buffersize+ubound(chunk) 'or if it's a fixed-size chunk, just use that number
        redim preserve mybuff(buffersize)
        for k%=0 to ubound(chunk) 'copy new information to buffersize
          mybuff(k%+buffersize-ubound(chunk))=chunk(k%)
        next
        

        如果您经常这样做(例如,每秒多次),您会想要执行类似于 StringBuilder 类的工作方式的操作:

        public BufSize&,BufAlloc& 'initialize bufalloc to 1 or a number >= bufsize
        public MyBuff() as byte
        
        sub getdata()
        bufsize=bufsize+ubound(chunk)
        if bufsize>bufalloc then
          bufalloc=bufalloc*2
          redim preserve mybuff(bufalloc)
        end if
        for k%=0 to ubound(chunk) 'copy new information to buffersize
          mybuff(k%+bufsize-ubound(chunk))=chunk(k%)
        next
        end sub
        

        每次指针经过缓冲区末尾时,基本上都会将分配给 mybuf 的内存加倍。这意味着更少的内存移动。

        【讨论】:

          猜你喜欢
          • 2023-04-05
          • 1970-01-01
          • 1970-01-01
          • 2022-01-25
          • 2019-03-30
          • 2010-11-25
          • 1970-01-01
          相关资源
          最近更新 更多