我正在开发一种工具来读取包含以下格式的值列表的Excel文件:
public function payments($trans){
dd($trans);
Excel::create('export_list_general', function ($file){
$file->sheet('export', function ($sheet) use ($trans) {
$sheet->setCellValue('A1', 'Client');
$sheet->setCellValue('B1', 'name');
$sheet->setCellValue('C1', 'surname');
$i = 2;
foreach ($trans as $tran) {
$sheet->setCellValue('A' . $i, $tran->name);
$sheet->setCellValue('B' . $i, $tran->pname);
$sheet->setCellValue('C' . $i, $tran->psurn);
$i++;
}
});
})->export('xlsx');
}
该工具使用空格作为分隔符来拆分每个项目的描述,然后检查英语和德语词典(该工具加载时将txt文件加载到字符串列表中)是否是单词。
即:
ID Description
1 AR2 KSRT FAN W32
2 KSK43 SRTS COOLER S324
3 RT7 MARS 0934X
如果单词上有数字或者它的长度小于3,我不会检查并假设它不是单词。
我正在使用LINQ拆分所有描述的值,然后获得不同的值(每个单词仅搜索一次)。
ID Words
1 AR2
1 KSRT
1 FAN
1 W32
然后再次使用LINQ来获取所有在描述中带有单词的条目。
List<string> distinctValues = dtCheck.AsEnumerable().SelectMany(r => r.Field<string>(columnName).Split(' ').Select(x => x).Where(s => s.All(char.IsLetter)).Where(y => y.Length > 2).ToList()).Distinct().ToList();
当前此过程大约需要40分钟,我是否可以做些改善性能的事情?
相关信息:
输入文件具有3.411个不同的“单词”。
词典文件中包含〜2.000.000个单词(包括品牌名称等)
对于每个单词,我调用以下函数:
dt = dtCheck.AsEnumerable().Where(x => x.Field<string>(columnName).Split(' ').Any(notNeutralValues.Contains)).CopyToDataTable();
答案 0 :(得分:1)
由于您的目标是提高性能,因此请执行以下步骤:
创建一个Hashset
展平数据,并使用Regex知道所有值是否都是字符。同样,这将消除对单独的Distinct
的要求,并且通过将StringComparer.OrdinalIgnoreCase
传递给构造函数来区分大小写
var dataHashSet = new HashSet<string>(dtCheck.AsEnumerable()
.SelectMany(r => r.Field<string>("columnName")
.Split(' ')
.Select(x => x)
.Where(s => s.Length > 2 && Regex.IsMatch(s, @"^[a-zA-Z]+$"))),StringComparer.OrdinalIgnoreCase)
使用PLinq并行处理dataHashSet
:
var result = dataHashSet.AsParallel().Where(x => isNeutralLanguage(x)).ToList();
在用于测试的方法isNeutralLanguage
中,确保实现如下:
var dict = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private bool isNeutralLanguage(string entry)
{
bool neutral = true;
var isMatch = dict.TryGetValue(entry,out string entryValue);
if (isMatch && entryValue != null )
neutral = false;
return neutral;
}
不区分大小写,类似于上面的Hashset
它是ConcurrentDictionary
,因为通话是multi-threaded
中性检查应为O(1)比较,而不是您正在执行的O(N),您可以根据逻辑要求并快速处理将给定键的值存储为null
布尔值,取决于Key是否存在。
根据需要对isNeutralLanguage
逻辑进行更改,我做了一些假设
随着算法的改进和处理的并行进行,这些更改将确保您的情况下性能更快得多