如果你事先知道你的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