OC

Knowledge OS
登录 注册
全部话题 移民 创业 iOS Mac Objective-C Swift Android 招聘 求职

程序设计的问题 c#

sirtel
sirtel 发布于 2017年02月16日
无人欣赏。

我打算写一个程序,调用dll,根据用户不同的设定,从服务器读取相应的数据。比如,用户需要设置为SettingOne的A型数据,则调用dll,设置一些参数,调用GetA()。

因为GetA()速度很慢,每次当用户想要A型数据时,需要很长的时间得到返回值,所以想"缓存"以前用过的数据。我在Obj class里,用了Dictionary<Setting, object> ObjValues记录之前获取过的数据。当setting一致时,如果字典里没有对应的值,则调用dll,若有,返回对应的值。

这里用Dictionary<Setting, object>不是最佳的做法吧?因为object还要被转换成string, int, double[]做余下的处理。

问题是,如何有效的"缓存"多种类型的数据,可以最快地查找到数据?

using System;
using System.Collections.Generic;
namespace test
{
 public static class DLL // cannot change the dll
 {
 public static int Setting1 { get; set; }
 public static int Setting2 { get; set; }
 public static string Setting3 { get; set; }
 public static string GetA() { /* Sleep(10 years) */ return ""; }
 public static int GetB() { /* Sleep(10 years) */ return 0; }
 public static double[] GetC() { /* Sleep(10 years) */ return new double[] { 0 }; }
 }
 public class Obj
 {
 public Dictionary<Setting, object> ObjValues = new Dictionary<Setting, object>();
 public void GetValue(Setting setting)
 {
 DLL.Setting1 = setting.Setting1; DLL.Setting2 = setting.Setting2; DLL.Setting3 = setting.Setting3;
 ObjValues[setting] = GetValue(setting.Type); // cache data
 }
 private object GetValue(ObjType type)
 {
 switch (type)
 {
 // loading data from database is assumed to be expensive.
 case ObjType.A: return DLL.GetA();
 case ObjType.B: return DLL.GetB();
 case ObjType.C: return DLL.GetC();
 default: return null;
 }
 }
 }
 public class Setting
 {
 public ObjType Type { get; set; }
 public int Setting1 { get; set; }
 public int Setting2 { get; set; }
 public string Setting3 { get; set; }
 }
 public enum ObjType { A, B, C, D, E }
 public class App
 {
 public static void Main(string[] args)
 {
 Obj obj = new Obj();
 List<Setting> settings = new List<Setting>() { /* SettingOne, SettingTwo, SettingThree ... */};
 foreach (Setting setting in settings)
 {
 if (obj.ObjValues.ContainsKey(setting))
 {
 Console.WriteLine(obj.ObjValues[setting]); // use the cached data
 }
 else
 {
 obj.GetValue(setting);
 Console.WriteLine(obj.ObjValues[setting]);
 }
 }
 }
 }
}
共3条回复
楼长 ·
tinyfool 回复于 2017年02月16日

Dictionary缓存成object还是什么,这跟性能关系不大。按照你的问题,只要你有缓存,性能就会比直接从网上拉快。

2楼 ·
xiaotie 回复于 2017年02月16日

这个性能没啥好操心的,直接用 Object 转来转去的就行了。当然,考虑提高那么一丁点儿性能,以及加上类型约束以免运行时出错,代码可以这样写:

void Main()
{
Setting<Int32> setting1 = new Setting<int> { Key = "setting1" };
setting1.Set(10);
Console.WriteLine(setting1.Get());
MySetting setting2 = new MySetting { Key = "mysetting" };
setting2.Set("blablabla......");
Console.WriteLine(setting2.Get());
}
public class Setting<T>
{
protected static Dictionary<Setting<T>, T> _cache = new Dictionary<Setting<T>, T>();
public string Key { get; set; } = String.Empty;
public T Get()
{
 T val = default(T);
 lock(_cache) 
 _cache.TryGetValue(this, out val);
 return val;
}
public void Set(T val)
{
 lock (_cache)
 _cache[this] = val;
}
public override int GetHashCode()
{
 return this.Key.GetHashCode();
}
}
public class MySetting : Setting<String> { }
3楼 ·
sirtel 回复于 2017年02月16日

2楼 @xiaotie 对对对,就是这样!应该用,避免出错

登录 或者 注册

AltStyle によって変換されたページ (->オリジナル) /