您是否真的對您的代碼進行了分析?請參閱Erik Lippert的performance rant:使用分析器或其他分析工具在開始調查替代方法之前根據經驗確定瓶頸的位置。例如,您的實際性能問題可能在BabysFirstsUsersDataEntities db
類中。
這就是說,我的直接反應是你有太多的數據中間表示,建設,人口和垃圾收集都需要時間。這些措施包括:
- 可能大到足以走在large object heap,從而永久性地損害性能和內存使用的過程的
jsonString
。
- 您的整個JSON層次結構的
JToken tok
表示形式。每個人JsonUserImageDTO
。
我建議的是儘可能多地消除這些中間表示。如the documentation中所建議的,您應該直接從流中加載,而不是加載到字符串並解析該字符串。
您也可以通過直接填充數據模型來消除JToken tok
。比方說,你的BabysFirstsUsersDataEntities
看起來像這樣(我只是猜測這裏):
public class BabysFirstsUsersDataEntities
{
public BabysFirstsUsersDataEntities() { this.UserImageLists = new List<UserImageList>(); }
public List<UserImageList> UserImageLists { get; set; }
}
public class UserImageList
{
public string email { get; set; }
public List<string> urlList;
}
而且你的DTO模式看起來是這樣的模型由http://json2csharp.com/提供:
public class RootObjectDTO
{
public ICollection<JsonUserImageDTO> results { get; set; }
}
public class JsonUserImageDTO
{
public ACL ACL { get; set; }
public string REID { get; set; }
public string createdAt { get; set; }
public string email { get; set; }
public string objectId { get; set; }
public string updatedAt { get; set; }
public int urlCount { get; set; }
public List<string> urlList { get; set; }
public UserImageList ToDataModel()
{
return new UserImageList { email = email, urlList = urlList };
}
}
public class Asdf
{
public bool read { get; set; }
public bool write { get; set; }
}
public class RoleAdmin
{
public bool read { get; set; }
}
public class ACL
{
public Asdf asdf { get; set; }
[JsonProperty("role:admin")]
public RoleAdmin RoleAdmin { get; set; }
}
然後創建下列通用ConvertingCollection<TIn, TOut>
工具類:
public class ConvertingCollection<TIn, TOut> : BaseConvertingCollection<TIn, TOut, ICollection<TIn>>
{
readonly Func<TOut, TIn> toInner;
public ConvertingCollection(Func<ICollection<TIn>> getCollection, Func<TIn, TOut> toOuter, Func<TOut, TIn> toInner)
: base(getCollection, toOuter)
{
if (toInner == null)
throw new ArgumentNullException();
this.toInner = toInner;
}
protected TIn ToInner(TOut outer) { return toInner(outer); }
public override void Add(TOut item)
{
Collection.Add(ToInner(item));
}
public override void Clear()
{
Collection.Clear();
}
public override bool IsReadOnly { get { return Collection.IsReadOnly; } }
public override bool Remove(TOut item)
{
return Collection.Remove(ToInner(item));
}
public override bool Contains(TOut item)
{
return Collection.Contains(ToInner(item));
}
}
public abstract class BaseConvertingCollection<TIn, TOut, TCollection> : ICollection<TOut>
where TCollection : ICollection<TIn>
{
readonly Func<TCollection> getCollection;
readonly Func<TIn, TOut> toOuter;
public BaseConvertingCollection(Func<TCollection> getCollection, Func<TIn, TOut> toOuter)
{
if (getCollection == null || toOuter == null)
throw new ArgumentNullException();
this.getCollection = getCollection;
this.toOuter = toOuter;
}
protected TCollection Collection { get { return getCollection(); } }
protected TOut ToOuter(TIn inner) { return toOuter(inner); }
#region ICollection<TOut> Members
public abstract void Add(TOut item);
public abstract void Clear();
public virtual bool Contains(TOut item)
{
var comparer = EqualityComparer<TOut>.Default;
foreach (var member in Collection)
if (comparer.Equals(item, ToOuter(member)))
return true;
return false;
}
public void CopyTo(TOut[] array, int arrayIndex)
{
foreach (var item in this)
array[arrayIndex++] = item;
}
public int Count { get { return Collection.Count; } }
public abstract bool IsReadOnly { get; }
public abstract bool Remove(TOut item);
#endregion
#region IEnumerable<TOut> Members
public IEnumerator<TOut> GetEnumerator()
{
foreach (var item in Collection)
yield return ToOuter(item);
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
現在,您可以填充你的db
直接如下:
var rootDTO = new RootObjectDTO
{
results = new ConvertingCollection<UserImageList, JsonUserImageDTO>(() => db.UserImageLists, (x) => { throw new NotImplementedException(); }, (x) => x.ToDataModel())
};
using (var stream = File.Open(path, FileMode.Open))
using (var reader = new StreamReader(stream))
{
JsonSerializer.CreateDefault().Populate(reader, rootDTO);
}
通過填充預分配rootDTO
和ConvertingCollection<UserImageList, JsonUserImageDTO>
,你db.UserImageLists
將得到填充了JSON的用更少的中間表示的內容。
1)您應該直接從'Stream'加載(http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JToken_Load.htm),而不是加載到大的中間字符串,然後解析字符串,正如[這裏](http://www.newtonsoft.com/json/help/html/Performance.htm)所解釋的那樣。 2)爲什麼內部循環內部的path.Contains(「UserImageList」)?如果這不是真的,你不能完全跳過文件嗎? – dbc
我將簽出#1並回報...#2指的是文件的名稱,它是我執行時處理的不同文件類型對應於不同模型的剩餘部分。我現在會改變它,因爲它使事情看起來比它們更復雜 – Jaked222
像這樣? StreamReader sr = new StreamReader(path); JsonReader reader = new JsonTextReader(sr); var tok = JObject.Load(reader); – Jaked222