Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.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
C# C将一个列表与另一个列表的一部分进行比较_C#_Performance_Linq_Loops - Fatal编程技术网

C# C将一个列表与另一个列表的一部分进行比较

C# C将一个列表与另一个列表的一部分进行比较,c#,performance,linq,loops,C#,Performance,Linq,Loops,我正在尝试从网站上删除不需要的图像。产品图像文件夹包含超过200000个图像。我有一个列表中不活动的产品代码列表。我在另一个列表中有文件名列表 List<string> lFileList = files.ToList(); List<string> lNotinfiles = new List<string>(); foreach (var s in lFileList) { var s2 = (from s3 in lProductsList

我正在尝试从网站上删除不需要的图像。产品图像文件夹包含超过200000个图像。我有一个列表中不活动的产品代码列表。我在另一个列表中有文件名列表

List<string> lFileList = files.ToList();
List<string> lNotinfiles = new List<string>();
foreach (var s in lFileList)
{
   var s2 = (from s3 in lProductsList 
             where s.Contains(s3.cProductCode) 
             select s3.cProductCode).FirstOrDefault();
   if (s2 == null)
   {
      lNotinfiles.Add(s);
   }
}
我试着一起移除同样不起作用的循环

更快实现这一目标的最佳方式应该是什么

我建议:使用HashSet,和ToList一起等待,也许还有GroupBy

HashSet+使用ToList

目前,代码的时间复杂度为on2—您迭代外部列表,并为每个项目迭代内部列表的所有项目

将LPProductsList的类型从列表更改为包含代码的哈希集。在HashSet中查找项是o1列表中的一项是启用的。然后,当您迭代lFileList的每一次以确定它们是否在lProductsList中时,它的时间复杂度将是on而不是on2

此代码将显示使用2个列表或使用列表和哈希集之间的时间差:

var items = (new[] { "1", "2", "3","4","5","6","7","8","9","10" }).SelectMany(x => Enumerable.Repeat(x, 10000)).ToList();
var itemsToFilterOut = new List<string> { "1", "2", "3" };

var efficientItemsToFilterOut = new HashSet<string>(itemsToFilterOut);

var watch = System.Diagnostics.Stopwatch.StartNew();
var unwantedItems = items.Where(item => itemsToFilterOut.Contains(item)).ToList();
watch.Stop();
Console.WriteLine(watch.TotalMilliseconds);

watch = Stopwatch.StartNew();
var efficientUnwantedItems = items.Where(item => efficientItemsToFilterOut.Contains(item)).ToList();
watch.Stop();
Console.WriteLine(watch.TotalMilliseconds);
群比

此外,您说过列表包含多个映射到同一个键的项。在筛选出之前使用GroupBy。检查此添加项的性能:

watch = Stopwatch.StartNew();
var moreEfficientUnwantedItems = items.GroupBy(item => item)
     .Where(group => efficientItemsToFilterOut.Contains(group.Key))
     .Select(group => group.Key);
watch.Stop();
Console.WriteLine(watch.TotalMilliseconds);

检查您的数据以分析它的重复量有多大,如果需要,请使用GroupBy

您正在将I assumearray转换为列表,然后执行foreach 直接在阵列上使用应该会使它至少快一点

List<string> lNotinfiles = new List<string>();
            for(int i = 0; i < files.Count(); i++)
            foreach (var s in files)
             {
                var s2 = (from s3 in lProductsList where s.Contains(s3.cProductCode) select s3.cProductCode).FirstOrDefault();
                if (s2 == null)
                   {
                      lNotinfiles.Add(s);
                   }
             }
两项建议:

不要具体化文件。ToList,即不要等到检索到所有文件 将NotInFiles组织为哈希集,使其具有更好的竞争力O1而不是ON。 大概是这样的:

  //TODO: you have to implement this 
  prtivate static String ExtractProductCode(string fileName) {
    int p = fileName.IndexOf('_');

    if (p >= 0)
      return fileName.SubString(0, p);
    else
      return fileName;  
  }


在这种情况下,watch.appead.totalMillimesons是访问ElapsedMillimesons的更好属性,因为TotalMillimesons是双精度,而ElapsedMillimesons是长型,将被舍入。没问题,仅供参考,ElapsedTicks也将遭受同样的命运,因为它也是一个长或int64。请确保在测量代码时在后面列出。选择:延迟执行将使您在代码段中达到目标。谢谢,是的,为了理解此问题。。。我无法测试它,因为我确实有时间做那个项目。
List<string> lNotinfiles = new List<string>();
            for(int i = 0; i < files.Count(); i++)
            foreach (var s in files)
             {
                var s2 = (from s3 in lProductsList where s.Contains(s3.cProductCode) select s3.cProductCode).FirstOrDefault();
                if (s2 == null)
                   {
                      lNotinfiles.Add(s);
                   }
             }
  //TODO: you have to implement this 
  prtivate static String ExtractProductCode(string fileName) {
    int p = fileName.IndexOf('_');

    if (p >= 0)
      return fileName.SubString(0, p);
    else
      return fileName;  
  }
  HashSet<String> NotInFiles = new HashSet<String>(
    lNotinfiles, 
    StringComparer.OrdinalIgnoreCase); // file names are case insensitive
  var files = Directory 
    .EnumerateFiles(@"C:\MyPictures", "*.jpeg", SearchOption.AllDirectories)
    .Where(path => Path.GetFileNameWithoutExtension(path))
    .Select(path => ExtractProductCode(path))
    .Where(code => !NotInFiles.Contains(code))
    .ToList(); // if you want List materialization