Vb.net 阵列求交函数速度

Vb.net 阵列求交函数速度,vb.net,function,array-intersect,Vb.net,Function,Array Intersect,我写了一个简短的数组求交函数,想知道为什么一个函数比另一个快 (一) Dim list2()作为字符串“假定它有值” Dim list2长度为整数=list2.length 函数newintersect(ByRef list1()作为字符串)作为字符串() Dim交叉点作为新阵列列表 如果(list1.Lengthlist2length),则“已更改>” “使用列表2” 对于列表2中的字符串形式的每一项 如果(Array.IndexOf(list1,thing)-1),那么 添加(事物) 如果结

我写了一个简短的数组求交函数,想知道为什么一个函数比另一个快

(一)

Dim list2()作为字符串“假定它有值”
Dim list2长度为整数=list2.length
函数newintersect(ByRef list1()作为字符串)作为字符串()
Dim交叉点作为新阵列列表
如果(list1.Length
(二)

Dim list2()作为字符串“假定它有值”
Dim list2长度为整数=list2.length
函数newintersect(ByRef list1()作为字符串)作为字符串()
Dim交叉点作为新阵列列表
如果(list1.Length>list2length),则“已更改>”
“使用列表2”
对于列表2中的字符串形式的每一项
如果(Array.IndexOf(list1,thing)-1),那么
添加(事物)
如果结束
下一个
其他的
“使用列表1”
对于列表1中的字符串形式的每一项
如果(Array.IndexOf(list2,thing)-1),那么
添加(事物)
如果结束
下一个
如果结束
返回交叉口
端函数
(三)

Dim list2()作为字符串“假定它有值”
Dim list2长度为整数=list2.length
函数newintersect(ByRef list1()作为字符串)作为字符串()
对于列表1中的字符串形式的每一项
如果(Array.IndexOf(list2,thing)-1),那么
添加(事物)
如果结束
下一个
返回交叉口
端函数
所以对于我的测试用例,1需要65秒,3需要63秒,而2实际需要75秒。有人知道为什么3是最快的吗?为什么1比2快


(很抱歉格式不好…似乎无法正确粘贴)

我希望您会发现,使用不同的测试用例,您可以逆转上面的结果,并达到2最快,1和3较慢的情况

在不知道测试用例组成的情况下很难进行评论,这将取决于两个数组中“相交”项的位置-如果这些项趋向于在一个数组上靠近前端,而在另一个数组上靠近末尾,那么数组迭代/IndexOf的嵌套顺序将具有明显不同的性能


顺便说一句-有更好的方法执行交集-排序一个或其他数组和执行二进制搜索是一种手段-使用字典(字符串…)或者类似的是另一种情况,两者都会带来更好的性能。

我希望您会发现,通过不同的测试用例,您可以逆转上面的结果,并达到2最快,1和3较慢的情况

在不知道测试用例组成的情况下很难进行评论,这将取决于两个数组中“相交”项的位置-如果这些项趋向于在一个数组上靠近前端,而在另一个数组上靠近末尾,那么数组迭代/IndexOf的嵌套顺序将具有明显不同的性能


顺便说一句-有更好的方法来执行交集-排序一个或其他数组并执行二进制搜索是一种方法-使用字典(字符串…)或类似的方法是另一种方法-并且两者都会产生更好的性能。

这没有多大区别。而且,这些方法似乎不会产生相同的结果,所以比较性能是没有意义的,对吗

无论如何,
Array.IndexOf
不是很有效的查找项目的方法,而且扩展性也不好。如果改用基于散列键的集合作为查找,您应该会得到显著的改进,如下所示:

Function newintersect(ByRef list1 As String(), ByRef list2 As String()) As String()
  Dim smaller As HashSet(Of String)
  Dim larger As String()
  If list1.Length < list2.Length Then
    smaller = New HashSet(Of String)(list1)
    larger = list2
  Else
    smaller = New HashSet(Of String)(list2)
    larger = list1
  End If
  Dim intersection As New List(Of String)
  For Each item As String In larger
    If smaller.Contains(item) Then
      intersection.Add(item)
    End If
  Next
  Return intersection.ToArray()
End Function
函数newintersect(ByRef list1作为String(),ByRef list2作为String())作为String()
变小为哈希集(字符串的)
变大为字符串()
如果list1.Length
这没什么区别。而且,这些方法似乎不会产生相同的结果,所以比较性能是没有意义的,对吗

无论如何,
Array.IndexOf
不是很有效的查找项目的方法,而且扩展性也不好。如果改用基于散列键的集合作为查找,您应该会得到显著的改进,如下所示:

Function newintersect(ByRef list1 As String(), ByRef list2 As String()) As String()
  Dim smaller As HashSet(Of String)
  Dim larger As String()
  If list1.Length < list2.Length Then
    smaller = New HashSet(Of String)(list1)
    larger = list2
  Else
    smaller = New HashSet(Of String)(list2)
    larger = list1
  End If
  Dim intersection As New List(Of String)
  For Each item As String In larger
    If smaller.Contains(item) Then
      intersection.Add(item)
    End If
  Next
  Return intersection.ToArray()
End Function
函数newintersect(ByRef list1作为String(),ByRef list2作为String())作为String()
变小为哈希集(字符串的)
变大为字符串()
如果list1.Length
这来自MSDN文档

    Dim id1() As Integer = {44, 26, 92, 30, 71, 38}
    Dim id2() As Integer = {39, 59, 83, 47, 26, 4, 30}

    ' Find the set intersection of the two arrays.
    Dim intersection As IEnumerable(Of Integer) = id1.Intersect(id2)

    For Each id As Integer In intersection
        Debug.WriteLine(id.ToString)
    Next

这来自MSDN文档

    Dim id1() As Integer = {44, 26, 92, 30, 71, 38}
    Dim id2() As Integer = {39, 59, 83, 47, 26, 4, 30}

    ' Find the set intersection of the two arrays.
    Dim intersection As IEnumerable(Of Integer) = id1.Intersect(id2)

    For Each id As Integer In intersection
        Debug.WriteLine(id.ToString)
    Next

哇…这有很大的不同…与=D之前的65秒相比,只需要3.3秒。但你确实犯了一个错误…它不应该有一个“不”…我正在做一个交叉点…“不”会给我所有不在每个列表中的。这也需要.NET3.5+,虽然这对我来说没问题,但是对于.NET2.0有类似的方法吗?@user389823:是的,交叉点。。。那就更合理了
    Dim id1() As Integer = {44, 26, 92, 30, 71, 38}
    Dim id2() As Integer = {39, 59, 83, 47, 26, 4, 30}

    ' Find the set intersection of the two arrays.
    Dim intersection As IEnumerable(Of Integer) = id1.Intersect(id2)

    For Each id As Integer In intersection
        Debug.WriteLine(id.ToString)
    Next