此代码大约需要30分钟和高CPU使用率,问题是什么
Do
strLine = objReader.ReadLine()
If strLine Is Nothing Then
Exit Do
End If
'check valid proxy
m = Regex.Match(strLine.Trim, strProxyParttern)
strMatch = m.Value.Trim
If String.IsNullOrEmpty(strMatch) = True OrElse _
strMatch.Contains("..") = True Then
Continue Do
End If
' create proxy
With tmpProxy
.IP = strMatch.Substring(0, strMatch.IndexOf(":"))
.Port = CInt(strMatch.Substring(strMatch.IndexOf(":") + 1))
.Status = "new"
End With
' check
If lstProxys.Contains(tmpProxy) = True Then
Continue Do
End If
lstProxys.Add(tmpProxy)
Debug.Print(lstProxys.Count.ToString)
Loop Until strLine Is Nothing
If lstProxys.Count < 1 Then
Exit Sub
End If
是比较缓慢还是阅读文件或正则表达式?
修改
像这样分析代码
Dim myTimer As New System.Diagnostics.Stopwatch()
Dim t1 As Integer = 0
Dim t2 As Integer = 0
Dim t3 As Integer = 0
'read the file line by line, collecting valid proxy
Do
'Read a line fromn the file
myTimer.Reset()
myTimer.Start()
strLine = objReader.ReadLine()
If strLine Is Nothing Then
Exit Do
End If
myTimer.Stop()
t1 = myTimer.Elapsed.Milliseconds
'check valid proxy
myTimer.Reset()
myTimer.Start()
m = Regex.Match(strLine.Trim, strProxyParttern)
strMatch = m.Value.Trim
If String.IsNullOrEmpty(strMatch) = True OrElse _
strMatch.Contains("..") = True Then
Continue Do
End If
myTimer.Stop()
t2 = myTimer.Elapsed.Milliseconds
' create proxy
myTimer.Reset()
myTimer.Start()
tmpProxy.IP = strMatch.Substring(0, strMatch.IndexOf(":"))
tmpProxy.Port = CInt(strMatch.Substring(strMatch.IndexOf(":") + 1))
tmpProxy.Status = "new"
' check
If lstProxys.Contains(tmpProxy) = True Then
Continue Do
End If
lstProxys.Add(tmpProxy)
myTimer.Stop()
t2 = myTimer.Elapsed.Milliseconds
Debug.Print(String.Format("Read={0}, Match={1}, Add={2}", t1, t2, t3))
Loop Until strLine Is Nothing
给出了这些结果
Read=0, Match=0, Add=1
Read=0, Match=0, Add=1
Read=0, Match=0, Add=2
...
Read=0, Match=0, Add=9
Read=0, Match=0, Add=9
Read=0, Match=0, Add=10
...
...
Read=0, Match=0, Add=39
Read=0, Match=0, Add=39
Read=0, Match=0, Add=40
etc
看起来代码没问题,除了添加到列表
答案 0 :(得分:2)
速度问题是因为您正在使用List(Of Structure)。 List.Contains方法是一个线性搜索(它遍历列表中的每个项目以查看它是否匹配)因此,您添加到列表中的唯一项目所需的时间越来越长。
因为您正在处理大量项目,所以将lstProxys更改为HashSet(Of T)。你会看到巨大的性能提升。您需要做的就是更改lstProxys的定义:
Dim lstProxys as New HashSet(Of structure)
答案 1 :(得分:1)
是比较缓慢还是阅读文件或正则表达式?
我们可以采取有根据的猜测,但为什么不测量它。
例如,在发布模式下单独运行以下三个测试,并且不附加调试器,看看需要多长时间
'Test 1 Just IO
Do
strLine = objReader.ReadLine()
Loop Until strLine Is Nothing
If lstProxys.Count < 1 Then
Exit Sub
End If
'Test 2 IO + Regex
Do
strLine = objReader.ReadLine()
If strLine Is Nothing Then
Exit Do
End If
'check valid proxy
m = Regex.Match(strLine.Trim, strProxyParttern)
strMatch = m.Value.Trim
If String.IsNullOrEmpty(strMatch) = True OrElse _
strMatch.Contains("..") = True Then
Continue Do
End If
Loop Until strLine Is Nothing
If lstProxys.Count < 1 Then
Exit Sub
End If
'Test 3 IO + regex and Compare
Do
strLine = objReader.ReadLine()
If strLine Is Nothing Then
Exit Do
End If
'check valid proxy
m = Regex.Match(strLine.Trim, strProxyParttern)
strMatch = m.Value.Trim
If String.IsNullOrEmpty(strMatch) = True OrElse _
strMatch.Contains("..") = True Then
Continue Do
End If
' create proxy
With tmpProxy
.IP = strMatch.Substring(0, strMatch.IndexOf(":"))
.Port = CInt(strMatch.Substring(strMatch.IndexOf(":") + 1))
.Status = "new"
End With
' check
If lstProxys.Contains(tmpProxy) = True Then
Continue Do
End If
lstProxys.Add(tmpProxy)
Debug.Print(lstProxys.Count.ToString)
Loop Until strLine Is Nothing
If lstProxys.Count < 1 Then
Exit Sub
End If
答案 2 :(得分:1)
磁盘I / O通常是此类限制因素。根据磁盘速度,您可以预期每秒大约5-20兆字节的吞吐量。
如果正则表达式包含导致大量回溯的表达式,那么正则表达式可能很慢,因此这是可能的,但与磁盘I / O相比,它应该是非常糟糕的。
由于代理列表中永远不会有多个项目,因此该比较不会成为问题。您不是创建任何新的代理对象,而是重用它,这意味着您更改已放入列表中的对象的属性。当您将对象与自身进行比较时,列表将始终包含第一次迭代后的对象,并且永远不会再次添加。
在为其属性赋值时,代理类是否执行任何操作?如果它确实像创建连接那样,那可能需要很长时间。