Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 从字典中检索记录的最快方法包含100万条记录_C#_Multithreading_Winforms_Collections - Fatal编程技术网

C# 从字典中检索记录的最快方法包含100万条记录

C# 从字典中检索记录的最快方法包含100万条记录,c#,multithreading,winforms,collections,C#,Multithreading,Winforms,Collections,我有一本字典,里面有一百万条记录;该键为数字键,其值为字符串。我想使用其值从集合中检索键 我的应用程序运行在多线程环境中 那么,最快的方法是什么呢?您的问题给人的印象是,您的字典在键和值之间有一对一的映射。如果是这种情况,并且字典不经常更改,并且如果您需要检索某个值的键,那么最快的方法是构建一个反向字典,其中原始字典中的值是键,键是值。这是一些前期工作,但之后会快得多: var revDict = new Dictionary<string, int>(); foreach (var

我有一本字典,里面有一百万条记录;该键为数字键,其值为
字符串
。我想使用其值从集合中检索键

我的应用程序运行在多线程环境中


那么,最快的方法是什么呢?

您的问题给人的印象是,您的字典在键和值之间有一对一的映射。如果是这种情况,并且字典不经常更改,并且如果您需要检索某个值的键,那么最快的方法是构建一个反向字典,其中原始字典中的值是键,键是值。这是一些前期工作,但之后会快得多:

var revDict = new Dictionary<string, int>();
foreach (var kvp in yourDict) revDict[kvp.Value] = kvp.Key;

您的问题给人的印象是,您的字典在键和值之间有一对一的映射。如果是这种情况,并且字典不经常更改,并且如果您需要检索某个值的键,那么最快的方法是构建一个反向字典,其中原始字典中的值是键,键是值。这是一些前期工作,但之后会快得多:

var revDict = new Dictionary<string, int>();
foreach (var kvp in yourDict) revDict[kvp.Value] = kvp.Key;

如果我可以假设您有一个带有键和值的双向一对一映射,并且您将从多个线程访问和更新字典,那么我建议您创建一个线程安全的双向字典

public class Map<T1, T2>
{
    private object _gate = new object();
    private Dictionary<T1, T2> _forward = new Dictionary<T1, T2>();
    private Dictionary<T2, T1> _reverse = new Dictionary<T2, T1>();

    public Map()
    {
        this.Forward = new Indexer<T1, T2>(_gate, _forward);
        this.Reverse = new Indexer<T2, T1>(_gate, _reverse);
    }

    public class Indexer<T3, T4>
    {
        private object _gate;
        private Dictionary<T3, T4> _dictionary;
        public Indexer(object gate, Dictionary<T3, T4> dictionary)
        {
            _dictionary = dictionary;
            _gate = gate;
        }
        public T4 this[T3 index]
        {
            get { lock (_gate) { return _dictionary[index]; } }
            set { lock (_gate) { _dictionary[index] = value; } }
        }
    }

    public void Add(T1 t1, T2 t2)
    {
        lock (_gate)
        {
            _forward.Add(t1, t2);
            _reverse.Add(t2, t1);
        }
    }

    public Indexer<T1, T2> Forward { get; private set; }
    public Indexer<T2, T1> Reverse { get; private set; }
}
公共类映射
{
私有对象_gate=新对象();
专用词典_forward=新词典();
私有字典_reverse=新字典();
公共地图()
{
this.Forward=新索引器(\u门,\u Forward);
this.Reverse=新索引器(_gate,_Reverse);
}
公共类索引器
{
私有对象门;
私人词典;
公共索引器(对象门、字典)
{
_字典=字典;
_门=门;
}
公共T4本[T3指数]
{
获取{lock({u gate){return{u dictionary[index];}}
设置{lock({u gate){u dictionary[index]=value;}}
}
}
公共空间添加(T1、T2)
{
锁(门)
{
_加上(t1,t2);
_相反。添加(t2,t1);
}
}
公共索引器转发{get;private set;}
公共索引器反向{get;private set;}
}
您可以这样使用它:

var map = new Map<int, string>();

map.Add(42, "Life");

Console.WriteLine(map.Forward[42]);
Console.WriteLine(map.Reverse["Life"]);
var-map=newmap();
添加(42,“生命”);
控制台写入线(地图转发[42]);
控制台写线(地图反转[“生活]);
这将产生:

Life 42 生活 42
如果我可以假设您有一个带有键和值的双向一对一映射,并且您将从多个线程访问和更新字典,那么我建议您创建一个线程安全的双向字典

public class Map<T1, T2>
{
    private object _gate = new object();
    private Dictionary<T1, T2> _forward = new Dictionary<T1, T2>();
    private Dictionary<T2, T1> _reverse = new Dictionary<T2, T1>();

    public Map()
    {
        this.Forward = new Indexer<T1, T2>(_gate, _forward);
        this.Reverse = new Indexer<T2, T1>(_gate, _reverse);
    }

    public class Indexer<T3, T4>
    {
        private object _gate;
        private Dictionary<T3, T4> _dictionary;
        public Indexer(object gate, Dictionary<T3, T4> dictionary)
        {
            _dictionary = dictionary;
            _gate = gate;
        }
        public T4 this[T3 index]
        {
            get { lock (_gate) { return _dictionary[index]; } }
            set { lock (_gate) { _dictionary[index] = value; } }
        }
    }

    public void Add(T1 t1, T2 t2)
    {
        lock (_gate)
        {
            _forward.Add(t1, t2);
            _reverse.Add(t2, t1);
        }
    }

    public Indexer<T1, T2> Forward { get; private set; }
    public Indexer<T2, T1> Reverse { get; private set; }
}
公共类映射
{
私有对象_gate=新对象();
专用词典_forward=新词典();
私有字典_reverse=新字典();
公共地图()
{
this.Forward=新索引器(\u门,\u Forward);
this.Reverse=新索引器(_gate,_Reverse);
}
公共类索引器
{
私有对象门;
私人词典;
公共索引器(对象门、字典)
{
_字典=字典;
_门=门;
}
公共T4本[T3指数]
{
获取{lock({u gate){return{u dictionary[index];}}
设置{lock({u gate){u dictionary[index]=value;}}
}
}
公共空间添加(T1、T2)
{
锁(门)
{
_加上(t1,t2);
_相反。添加(t2,t1);
}
}
公共索引器转发{get;private set;}
公共索引器反向{get;private set;}
}
您可以这样使用它:

var map = new Map<int, string>();

map.Add(42, "Life");

Console.WriteLine(map.Forward[42]);
Console.WriteLine(map.Reverse["Life"]);
var-map=newmap();
添加(42,“生命”);
控制台写入线(地图转发[42]);
控制台写线(地图反转[“生活]);
这将产生:

Life 42 生活 42
欢迎来到SO。你要求的是最快的,但你没有表现出你的努力。因此,不要为自己编写代码,没有显示的问题往往会被关闭。如果您有代码,codereview可能是询问字典中是否有重复值的可能重复的更好地方?您是只想检索一个密钥还是需要检索多个密钥?有太多不清楚的方面。您的收藏将从不同的线程访问吗?你的收藏会变异吗?如果是,则集合的预期读写比率是多少?注意:“在多线程环境中运行”不明确;这是“多线程同时读写”吗?“多个线程读取,只有一个线程写入”?“多线程读取,数据一经构建就不会改变”,等等;这真的很重要欢迎来到这里。你要求的是最快的,但你没有表现出你的努力。因此,不要为自己编写代码,没有显示的问题往往会被关闭。如果您有代码,codereview可能是询问字典中是否有重复值的可能重复的更好地方?您是只想检索一个密钥还是需要检索多个密钥?有太多不清楚的方面。您的收藏将从不同的线程访问吗?你的收藏会变异吗?如果是,则集合的预期读写比率是多少?注意:“在多线程环境中运行”不明确;这是“多线程同时读写”吗?“多个线程读取,只有一个线程写入”?“多线程读取,数据一经构建就不会改变”,等等;这真的,真的很重要,不知道为什么会被否决;这是一个很好的答案,特别是它解释了警告(一对一)