.net 使用For循环优化大数据比较
好吧,这是交易,伙计们。我有两个文本文件。每个包含.net 使用For循环优化大数据比较,.net,vb.net,algorithm,optimization,.net,Vb.net,Algorithm,Optimization,好吧,这是交易,伙计们。我有两个文本文件。每个包含500行行(句子) 我已经将它们加载到内存中到它们自己的数组中(数据类型:string)。让我们命名数组A和B 接下来,我在数组A中获得第一句,使用空格作为分隔符将其拆分为另一个数组C,以获得单词 然后,对于数组B中的每个句子,我将其拆分为数组D,再次使用空格作为分隔符来获取单词,并将数组C中的每个单词与数组D中的每个单词进行比较,计算两个句子之间的匹配百分比 我计算数组A中第一个句子与数组B中所有句子的平均匹配百分比 然后我将其存储到数组E中,
500行
行(句子)
我已经将它们加载到内存中
到它们自己的数组中(数据类型:string)。让我们命名数组A和B
接下来,我在数组A
中获得第一句
,使用空格
作为分隔符将其拆分为另一个数组C
,以获得单词
然后,对于数组B
中的每个句子,我将其拆分为数组D
,再次使用空格
作为分隔符来获取单词,并将数组C
中的每个单词与数组D
中的每个单词进行比较,计算两个句子之间的匹配百分比
我计算数组A
中第一个句子与数组B
中所有句子的平均匹配百分比
然后我将其存储到数组E
中,其中包含数组A
的所有句子及其平均匹配百分比
对于数组A中的每个标题,我都使用上面的第一句来执行操作
问题是处理数组A中的每个标题大约需要15秒。我是否可以优化这段时间以加快速度
硬件:AMD Phenom I 32位四核
代码:
Imports System.IO
Imports System.Object
Imports System.Xml
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
'Important File Paths
Dim titlesFilePath As String = Environment.CurrentDirectory & "\titles.txt"
Dim xmlTitlesFilePath As String = Environment.CurrentDirectory & "\extractedTitles.txt"
Dim stopWordsFilePath As String = Environment.CurrentDirectory & "\stopWords.txt"
'Import Important Data From Files -> Memory
Dim titles As Array = FileToArray(titlesFilePath)
Dim stopWords As Array = FileToArray(stopWordsFilePath)
Dim xmlDataUnprocessed As Array = FileToArray(xmlTitlesFilePath)
'Delimters To Filter Titles For
Dim userDefinedDelimeters(4, 1)
userDefinedDelimeters(0, 0) = "-"
userDefinedDelimeters(0, 1) = " "
userDefinedDelimeters(1, 0) = ","
userDefinedDelimeters(1, 1) = " "
userDefinedDelimeters(2, 0) = "—"
userDefinedDelimeters(2, 1) = " "
userDefinedDelimeters(3, 0) = "'s"
userDefinedDelimeters(3, 1) = ""
userDefinedDelimeters(4, 0) = "'"
userDefinedDelimeters(4, 1) = " "
'Declare Important Variables
Dim xmlData(xmlDataUnprocessed.Length / 2, 1)
Dim xmlTurn = 0
Dim xmlDataCount = 0
'Create Feed Title/URL Array
For i = 0 To (xmlDataUnprocessed.Length - 1)
If xmlTurn = 0 Then
xmlData(xmlDataCount, 0) = xmlDataUnprocessed(i)
xmlTurn = 1
Else
xmlData(xmlDataCount, 1) = xmlDataUnprocessed(i)
xmlTurn = 0
xmlDataCount += 1
End If
Next
'CPU-Intensive Stuff Occurs
Dim xmlTitle As String
Dim xmlTitleWords As Array
Dim savedTitleWords As Array
Dim titleResults(xmlData.GetUpperBound(0) - 1, 1)
Dim titlePercentageMatch As Integer
Dim numberOfTitlesMatched As Integer
For i = 0 To xmlData.GetUpperBound(0) - 1
Console.WriteLine("Working On Title No. " & i & " Out Of " & xmlData.GetUpperBound(0) - 1)
titlePercentageMatch = 0
numberOfTitlesMatched = 0
xmlTitle = xmlData(i, 0)
xmlTitle = processTitle(stopWords, userDefinedDelimeters, xmlTitle)
xmlTitleWords = xmlTitle.Split(" ")
For Each title In titles
title = processTitle(stopWords, userDefinedDelimeters, title)
savedTitleWords = title.split(" ")
Dim compareResult = compareTitle(xmlTitleWords, savedTitleWords)
If compareResult > 0 Then
titlePercentageMatch += compareResult
numberOfTitlesMatched += 1
End If
Next
titleResults(i, 0) = xmlData(i, 0)
titleResults(i, 1) = (titlePercentageMatch / numberOfTitlesMatched)
Next
For i = 0 To titleResults.GetUpperBound(0) - 1
Console.WriteLine(titleResults(i, 0) & " ---> " & titleResults(i, 1) & vbCrLf)
Next
Console.Read()
End Sub
Function compareTitle(ByRef xmlTitleWords As Array, ByRef savedTitleWords As Array)
Dim NumberOfMatches = 0
For Each xmlWord In xmlTitleWords
For Each savedWord In savedTitleWords
If (xmlWord.ToString.ToLower = savedWord.ToString.ToLower) Then
NumberOfMatches += 1
End If
Next
Next
Return ((NumberOfMatches / xmlTitleWords.Length) * 100)
End Function
Function processTitle(ByRef stopWordArray As Array, ByRef delimArray As Array, ByVal title As String)
title = removeStopWords(stopWordArray, title)
title = removeDelims(delimArray, title)
Return title
End Function
Function removeStopWords(ByRef stopWordsArray As Array, ByVal sentence As String)
For i = 0 To stopWordsArray.Length - 1
If sentence.ToLower.Contains(" " & stopWordsArray(i).ToString.ToLower & " ") = True Then
sentence = Microsoft.VisualBasic.Strings.Replace(sentence, " " & stopWordsArray(i) & " ", " ", 1, -1, Constants.vbTextCompare)
'ElseIf sentence.ToLower.Contains(stopWordsArray(i).ToString.ToLower & " ") = True Then
'sentence = Microsoft.VisualBasic.Strings.Replace(sentence, stopWordsArray(i) & " ", "", 1, -1, Constants.vbTextCompare)
End If
sentence = Regex.Replace(sentence, "\s+", " ")
Dim Words = sentence.ToLower.Split(" ")
If Words(0).ToString.ToLower & " " = stopWordsArray(i).ToString.ToLower & " " Then
sentence = sentence.Remove(0, stopWordsArray(i).ToString.ToLower.Length + 1)
End If
Words = sentence.ToLower.Split(" ")
Dim LastWord = Words(Words.Length - 1)
'Console.WriteLine(LastWord & "++")
If " " & LastWord.ToString.ToLower = " " & stopWordsArray(i).ToString.ToLower Then
sentence = sentence.Remove(sentence.Length - 1 - LastWord.Length, stopWordsArray(i).ToString.ToLower.Length + 1)
End If
Next
sentence = Regex.Replace(sentence, "\s+", " ")
Return sentence
End Function
Function removeDelims(ByRef delimArray As Array, ByVal sentence As String)
For i = 0 To delimArray.GetUpperBound(0) - 1
sentence = sentence.Replace(delimArray(i, 0), delimArray(i, 1))
Next
sentence = Regex.Replace(sentence, "\s+", " ")
Return sentence
End Function
Function FileToArray(ByVal filePath As String) As String()
Dim content As String
Dim lines As New ArrayList
Dim sr As System.IO.StreamReader
' read the file's lines into an ArrayList
Try
sr = New System.IO.StreamReader(filePath)
Do While sr.Peek() >= 0
lines.Add(sr.ReadLine())
Loop
Finally
If Not sr Is Nothing Then sr.Close()
End Try
' convert from ArrayList to a String array
Return CType(lines.ToArray(GetType(String)), String())
End Function
End Module
编辑:我希望不要太混乱。对不起!
编辑2:提供的酱汁:P只读
数组B
,然后逐行读取数组A
如果适用,请使用StringBuilder而不是字符串
另外,看看是否可以使用并行处理,即:任务
至于距离,匹配算法,你们并没有提到它是什么,它是如何工作的。这很难说。立即将数组B只读到内存中,然后逐行读取数组A
如果适用,请使用StringBuilder而不是字符串
另外,看看是否可以使用并行处理,即:任务
至于距离,匹配算法,你们并没有提到它是什么,它是如何工作的。很难说清楚。你有几件事让自己慢了下来
If(xmlWord.ToString.ToLower=savedWord.ToString.ToLower)则
为什么不在将其放入数组之前将所有内容更改为小写
title=processTitle(stopWords、userDefinedDelimeters、title)
为什么不在将其加载到阵列之前执行此操作
提前完成所有的处理,然后分别进行比较。你在做一些事情,让自己慢了一点
If(xmlWord.ToString.ToLower=savedWord.ToString.ToLower)则
为什么不在将其放入数组之前将所有内容更改为小写
title=processTitle(stopWords、userDefinedDelimeters、title)
为什么不在将其加载到阵列之前执行此操作
提前进行所有处理,然后分别进行比较。您的基本算法是N*M*A2其中
- N=第一个文件中的标题数
- M=第二个文件中的标题数
- A=每个标题的平均字数
如果有500*500*52,则推送6250000个不区分大小写的字符串。但如果你就是这么做的话。内部循环根据外部循环的长度为每个title
调用processTitle
。它不需要这样做
单螺纹
您可以做的是有一个预处理步骤,将每个单词替换为表示该单词的整数(符号)。为此,您可以使用字典查找符号,如果没有,则指定一个新的唯一符号(例如,保留一个整数计数器并使用下一个值)
然后,您的主处理循环将与以前类似,但您正在进行整数比较(速度要快得多)。事实上,您希望此处理步骤只进行比较和统计数据收集。其他一切都应该搬出去
多线程
保持你的预处理步骤
并行化处理步骤。一种方法是用于最外层的循环:Parallel.for(0,xmlData.GetUpperBound(0)-1,Sub(i)…End Sub)
,其中操作是从上面开始的循环体。TPL可能会很好地平衡负载(平均使用4个内核)
另一种方法是使用任务并行库来加速处理1/4数据的任务。然后开始使用结果的延续。您的基本算法是N*M*A2其中
- N=第一个文件中的标题数
- M=第二个文件中的标题数
- A=每个标题的平均字数
如果有500*500*52,则推送6250000个不区分大小写的字符串。但如果你就是这么做的话。内部循环根据外部循环的长度为每个title
调用processTitle
。它不需要这样做
单螺纹
您可以做的是有一个预处理步骤,将每个单词替换为表示该单词的整数(符号)。为此,您可以使用字典查找符号,如果没有,则指定一个新的唯一符号(例如,保留一个整数计数器并使用下一个值)
然后,您的主处理循环将与以前类似,但您正在进行整数比较(速度要快得多)。事实上,您希望此处理步骤只进行比较和统计数据收集。其他一切都应该搬出去
多线程
保持你的预处理步骤
并行化处理步骤。一种方法可以做到这一点