如果你事先知道你的4名標準的字符串,你可以用String.Intern()
實習生(或直接聲明爲字符串文字的地方 - 即不工作),然後使用下面的custom JsonConverter
所有JSON字符串文字轉換爲他們的實習值,如果找到一個:
var settings = new JsonSerializerSettings { Converters = new [] { new InternedStringConverter() } };
var root = JsonConvert.DeserializeObject<RootObject>(jsonString, settings);
你也可以將它應用於使用JsonPropertyAttribute.ItemConverterType
特定的字符串集合:
public class InternedStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var s = reader.TokenType == JsonToken.String ? (string)reader.Value : (string)JToken.Load(reader); // Check is in case the value is a non-string literal such as an integer.
return String.IsInterned(s) ?? s;
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
這可以通過串行設置全局應用:
public class Group
{
[JsonProperty(ItemConverterType = typeof(InternedStringConverter))]
public List<string> StandardStrings { get; set; }
}
如果你不提前知道的四根弦,你可以創建一個實習生串轉換器因爲他們正在閱讀:
public class AutoInterningStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
// CanConvert is not called when a converter is applied directly to a property.
throw new NotImplementedException("AutoInterningStringConverter should not be used globally");
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var s = reader.TokenType == JsonToken.String ? (string)reader.Value : (string)JToken.Load(reader); // Check is in case the value is a non-string literal such as an integer.
return String.Intern(s);
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
不過,我強烈反對全球使用這因爲你可能最終將大量的字符串添加到內部字符串表中。相反,只有它適用於特定字符串集合(S),你有信心含有少量的唯一字符串的副本:
public class Group
{
[JsonProperty(ItemConverterType = typeof(AutoInterningStringConverter))]
public List<string> StandardStrings { get; set; }
}
更新
從你更新的問題,我看你具有標準值的字符串屬性,而不是具有標準值的字符串集合。因此,你應該使用每個[JsonConverter(typeof(AutoInterningStringConverter))]
:
public class Group
{
[JsonConverter(typeof(AutoInterningStringConverter))]
public string groupName { get; set; }
public string code { get; set; }
}
來源
2016-01-20 16:58:20
dbc
這是否真的是你的應用程序的瓶頸? 40,000個參考文獻聽起來不多。 – Habib
這篇關於JSON.NET 8的博客文章可能會引起您的興趣(儘管不是您的問題的直接答案):http://james.newtonking.com/archive/2015/12/20/json-net-8-0- release-1-allocation-and-bug-fixes – CodingGorilla
@Habib,這實際上不是問題,內存佔用可以忽略不計,但如果內存分配較少,我仍然會更喜歡它,爲什麼40000有四個! – BastanteCaro