【问题标题】:File IO duplicate checking more efficient?文件 IO 重复检查更高效?
【发布时间】:2010-12-17 14:14:54
【问题描述】:

基本上我有这个应用程序,它扫描文件夹中的所有 mp3,并返回一个没有重复的文件列表。我有两种方法来执行此任务。第一个删除重复的文件名,第二个删除具有匹配 mp3 IDv3 标签的重复文件。

但是我的文件夹有大约 5000 个文件,它成功地删除了重复文件到 4900 个,但这需要很长时间!任何人都可以提出更有效的方法吗?我使用并行性使事情尽可能快,但它仍然很慢。

删除重复文件名的第一种方法:

private static IEnumerable<string> GetFilesFromDir(string dir)
        {
            return Directory.GetFiles(dir, "*.mp3", SearchOption.AllDirectories).Distinct();
        }

第二种方法遍历上述方法返回的每个文件,并检查其 IDv3 标签(艺术家 - 歌曲名称)信息,以确保不存在重复歌曲。

private static IEnumerable<string> RemoveDuplicates(IEnumerable<string> files)
{
    var dictionary = new ConcurrentDictionary<string, string>();

    Parallel.ForEach(files, f =>
                                {
                                    string tag = SongInformation.ArtistTitleAlbumString(f);
                                    dictionary.TryAdd(tag, f);
                                });

    return dictionary.Values;
}

这两个方法调用如下:

var newFiles = RemoveDuplicates(GetFilesFromDir(Settings.SharedFolder));

【问题讨论】:

  • 描述您现有的解决方案。例如,如果瓶颈在 I/O 中,那么巧妙地使用这个“外部”代码可能没有多大帮助。另外,Parallel.ForEach 版本的机器上的 CPU 使用率是多少?
  • 双核和四核机器上的 CPU 使用率非常低(大约 1-8%)。
  • 我不知道你为什么要做 Parallel.ForEach。 ConcurrentDictionary 无论如何都是同步的,因此您不会分配太多处理。
  • “CPU 使用率非常低(大约 1-8%)” - 这是一个 strong 标志,表明这是 I/O 绑定的。请通过分析器确认。
  • 所以说它是 I/O 绑定的,在不改变硬件的情况下我可能无法加快速度?

标签: c# file io mp3 parallel-processing


【解决方案1】:

对Distinct() 的调用在这里似乎毫无意义。 Directory.GetFiles() 返回完整的文件名(带路径),因此它们始终是不同的。

【讨论】:

  • ArtistTitleAlbumString 需要不同,而不是文件名/路径
  • 我同意删除 Distinct() 部分。有道理,但不知道为什么我首先把它放在那里。
猜你喜欢
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 2018-06-08
  • 2014-04-13
  • 2019-04-16
  • 2013-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多