Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要VB.net高效内存功能_.net_Performance_Arraylist_Memory Management_String Concatenation - Fatal编程技术网

需要VB.net高效内存功能

需要VB.net高效内存功能,.net,performance,arraylist,memory-management,string-concatenation,.net,Performance,Arraylist,Memory Management,String Concatenation,当RowCollection为50000+时,我将从以下函数中获得内存不足异常,因此我需要使其更高效地使用内存。该函数只需构造存储在RowCollection中的行索引的逗号分隔字符串即可。有人能在下面的例子中发现任何明显的内存不足操作吗 N.B RowCollection只包含存储为整数的行索引列表 Private Function GetCommaSeparatedString(ByRef RowIndexes As ArrayList) As String Dim Row

当RowCollection为50000+时,我将从以下函数中获得内存不足异常,因此我需要使其更高效地使用内存。该函数只需构造存储在RowCollection中的行索引的逗号分隔字符串即可。有人能在下面的例子中发现任何明显的内存不足操作吗

N.B RowCollection只包含存储为整数的行索引列表

 Private Function GetCommaSeparatedString(ByRef RowIndexes As ArrayList) As String
        Dim RowString As String = String.Empty

        'Build a string of the row indexes 
        'Add one onto each index value so our indexes begin at 1 
        For Each Row In RowIndexes 
            RowString += CInt(Row.ToString) + 1 & ","
        Next

        'Remove the last comma
        If RowString.Length > 0 Then
            RowString = RowString.Substring(0, RowString.Length - 1)
        End If

        Return RowString
    End Function

提前感谢。

这是因为在每次迭代中,您在幕后创建了两个字符串,并且它们在接近结束时变得越来越大。

“1,2,3,4,5,….499500” “1,2,3,4,5,….499500,”

仅在500次迭代结束时,您就创建了2个长度接近2000个字符的字符串,但在下一次迭代中却被丢弃(但运行时可能会保留它们)

在上一次迭代中,假设行索引是连续的,则字符串(从1到50000)的长度将为100000个字符。这意味着您已经分配了大约1000000000个字符或(我相信2字节/字符)20GB的字符串

您可以在字符串(行字符串)上使用
StringBuilder
而不是
+=

Ex

Dim RowString As StringBuilder = new StringBuilder( 100000 )

For Each Row In RowIndexes 
    RowString.Append( CInt(Row.ToString) + 1).Append( "," )
Next

'...'

Return RowString.ToString
您也可以尝试下一种方法,但您应该分析这两种方法,并为自己选择最佳方法。

Private Function GetCommaSeperatedString(ByRef RowIndexes As ArrayList) As String
    Dim indexArray as String[] = RowIndexes
                                 .Select(Function(r)=> (CInt(r.ToString) + 1)ToString)
                                 .ToArray
    return String.Join( ',', indexArray)
End Function



*注意:这是我写过的VB的第一行,所以我可能犯了一个基本的错误(特别是在linq/lambda的东西中),但关键在于此。

更新:虽然这是对使用stringbuilder的一个直接更改,但请查看或

当然,您可能仍然会耗尽内存(毕竟内存是有限的),但您应该使用StringBuilder,而不是串联字符串。每次都是创建一个新的字符串对象,而不是更改它(因为字符串是不可变的)


StringBuilder
是个好主意,但是为什么不通过流式输出来避免问题,而不是尝试一次将其全部保存在内存中?

我不确定为什么会出现内存不足错误,除非行的字符串表示非常大,因为您从来没有超过一个或两个不可垃圾回收的字符串

然而,您的方法效率极低,因为它花费了大量时间复制半构建字符串的内容。StringBuilder在构建大型字符串时更合适,因为它可以在每次不重新创建内容的情况下进行修改

但是,在这种情况下,即使是StringBuilder也不是一个好主意,因为您正在连接字符串,并且已经有了一个方法:String.Join。只需使用LINQ查询将一个添加到索引中,就可以得到一行:

Private Function GetCommaSeparatedString(ByVal RowIndexes As ArrayList) As String
    Return String.Join(",", From index In RowIndexes Select CInt(index) + 1)
End Function

我还建议不要通过引用传递,除非您确实需要它。您没有修改行索引,所以按值传递它。我也不知道为什么要对索引执行字符串(),然后立即对其进行解析。它们不是已经是整数了吗?只需使用CInt。

正确的拼写是“分开的”。在旁注中,为什么
ArrayList
?这看起来像是
List
@Steven Sudit的一个作业,它有我想要的答案-流式处理,或者根据需要创建并丢弃每一行。我无法立即想到一个需要整个内容作为字符串的有效设计。我完全同意你的观点,尽管如果可能的话,我可能会用这个方法重新设计代码。@PhilipRieck“stream it out”是什么意思?@Strilan要么创建一个IEnumerable方法来获取行,或者通过添加逗号等的文本阅读器来阅读,也就是说,不要试图一次从内存中处理整个文件。@Strilanc感谢到目前为止的所有评论。。。我无法流式处理结果,因此使用字符串生成器或string.Join似乎是最好的方法。如果Option Strict On,上述行会变成什么?我还没有学会使用Linq。谢谢,问题解决了。谢谢你的帮助。
Private Function GetCommaSeparatedString(ByVal RowIndexes As ArrayList) As String
    Return String.Join(",", From index In RowIndexes Select CInt(index) + 1)
End Function