另外,对于Size方法,MapCodeGenResolver的处理也是非常快速的,因为它已经提前计算好了元数据的大小,并且内联了基元字段本身的固定大小.
Bssom.Net中目前拥有5个特性.
AliasAttribute : 别名特性, 用于修改Map格式对象字段在二进制中所保存的字段名称
BssomFormatterAttribute : 自定义格式化特性, 当字段属性或类型被该特性标记后, 此类型的格式化将采用该特性所指定的格式化器
IgnoreKeyAttribute : 忽略某一个Key, 序列化时将忽略被标记的字段, 适用于Map格式
OnlyIncludeAttribute : 仅包含某一个Key, 序列化时仅包含该Key, 适用于Map格式, 与IgnoreKeyAttribute作用相反,优先级更高
SerializationConstructorAttribute : 为类型的反序列化指定一个构造函数
10.更多的可能性你可以自己编写, 编写, 也可以定义你自己的特性, 也可以封装用于序列化的, 并且Bssom.Net还提供了上下文的支持, 这可以让序列化行为变得多样性.
如果你能为Bssom.Net提供有用或者侧重于高性能的扩展包, 那么请您告诉我.
下面示例编写了以String类型为原型的解析器, 该解析器通过与上下文交互的方式来带来字符串类型序列化性能的提升.
public sealed class MyStringFormatterResolver : IFormatterResolver { public static MyStringFormatterResolver Instance = new MyStringFormatterResolver(); public IBssomFormatter<T> GetFormatter<T>() { return FormatterCache<T>.Formatter; } private static class FormatterCache<T> { public static readonly IBssomFormatter<T> Formatter; static FormatterCache() { if (typeof(T) == typeof(string)) Formatter = (IBssomFormatter<T>)(object)MyStringFormatter.Instance; } } } public sealed class MyStringFormatter : IBssomFormatter<string> { public static MyStringFormatter Instance = new MyStringFormatter(); public string Deserialize(ref BssomReader reader, ref BssomDeserializeContext context) { if (reader.TryReadNull()) { return null; } reader.EnsureType(BssomType.StringCode); int dataLen = reader.ReadVariableNumber(); ref byte refb = ref reader.BssomBuffer.ReadRef((int)dataLen); fixed (byte* pRefb = &refb) { return new string((sbyte*)pRefb, 0, (int)dataLen, UTF8Encoding.UTF8); } } public void Serialize(ref BssomWriter writer, ref BssomSerializeContext context, string value) { if (value == null) { writer.WriteNull(); return; } int valueUtf8Size = context.ContextDataSlots.PopMyStringSize(); writer.WriteBuildInType(BssomType.StringCode); writer.WriteVariableNumber(valueUtf8Size); ref byte refb = ref writer.BufferWriter.GetRef(valueUtf8Size); fixed (char* pValue = value) fixed (byte* pRefb = &refb) { UTF8Encoding.UTF8.GetBytes(pValue, value.Length, pRefb, valueUtf8Size); } writer.BufferWriter.Advance(valueUtf8Size); } public int Size(ref BssomSizeContext context, string value) { if (value == null) return BssomBinaryPrimitives.NullSize; int dataSize = UTF8Encoding.UTF8.GetByteCount(value); context.ContextDataSlots.PushMyStringSize(dataSize); return BssomBinaryPrimitives.BuildInTypeCodeSize + dataSize; } } public void MyTest() { var option = BssomSerializerOptions.Default.WithFormatterResolver(MyStringFormatterResolver.Instance); string str = RandomHelper.RandomValue<string>(); BssomSizeContext sizeContext = new BssomSizeContext(option); int len = BssomSerializer.Size(ref sizeContext, str); if (len > 1000) throw new Exception("Size of value storage binary exceeded"); BssomSerializeContext serContext = new BssomSerializeContext(option); sizeContext.ContextDataSlots.SetMyStringStack(serContext.ContextDataSlots); var bytes = BssomSerializer.Serialize(ref serContext, str); var deStr = BssomSerializer.Deserialize<string>(bytes); Assert.Equal(str,deStr); }上面的代码是单独为String定义了一个新的解析器和新的格式化器, 该格式化器可以将Size方法中对字符串计算的UTF8大小存储在上下文中, 这样在序列化时不用重复对String再做一次UTF8大小计算.
11.如何使用Bssom.Net是无合约的, 开箱即用, 这里有些示例代码.
Size方法用于 获取对象被序列化后的二进制数据大小,高性能的内部实现,几乎无开销
//获取值被序列化后的大小 object value = RandomHelper.RandomValue<object>(); int size = BssomSerializer.Size(value, option: BssomSerializerOptions.Default); //使用上下文获取值被序列化后的大小 BssomSizeContext context = new BssomSizeContext(BssomSerializerOptions.Default); object value = RandomHelper.RandomValue<object>(); int size = BssomSerializer.Size(ref context, value); Serialize