using System; using System.Diagnostics; using System.IO; using MongoDB.Bson; using MongoDB.Bson.IO; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Attributes; namespace MongoPerf { class Program { static void Main(string[] args) { var afr = new ArticleForRanking { AggregatedRank = 123, ArticleId = 1000000, BigImagesCount = 10, BodyLength = 1234, FacebookShares = 1000, ImageClusterId = 10000000, MediaId = 123123, Published = DateTime.Now, ShardKey = 123, TweetsCount = 10000, VideoCount = 10, VideoId = 1231231 }; var bson = afr.ToBson(); const int iter = 500000; var sw = Stopwatch.StartNew(); for (int i = 0; i < iter; i++) { BsonSerializer.Deserialize(bson); } sw.Stop(); Console.WriteLine("BsonSerializer {0}, avg: {1} ops/sec", sw.Elapsed, (int)(iter / sw.Elapsed.TotalSeconds)); sw = Stopwatch.StartNew(); for (int i = 0; i < iter; i++) { DeserializeManual(bson); } sw.Stop(); Console.WriteLine("DeserializeManual {0}, avg: {1} ops/sec", sw.Elapsed, (int)(iter / sw.Elapsed.TotalSeconds)); } static ArticleForRanking DeserializeManual(byte[] bson) { var afr = new ArticleForRanking(); using (var ms = new MemoryStream (bson)) { var reader = BsonReader.Create(ms); var propName = ""; var currentType = BsonType.Null; while (true) { switch (reader.State) { case BsonReaderState.Initial: reader.ReadStartDocument(); break; case BsonReaderState.Type: currentType = reader.ReadBsonType(); break; case BsonReaderState.Name: propName = reader.ReadName(); break; case BsonReaderState.Value: switch (propName) { case "_id": afr.ArticleId = reader.ReadInt64(); break; case "Published": afr.Published = DateTime.FromBinary(reader.ReadDateTime()); break; case "ShardKey": afr.ShardKey = reader.ReadInt32(); break; case "MediaId": afr.MediaId = reader.ReadInt64(); break; case "AggregatedRank": afr.AggregatedRank = reader.ReadDouble(); break; case "BigImagesCount": afr.BigImagesCount = reader.ReadInt32(); break; case "VideoCount": afr.VideoCount = reader.ReadInt32(); break; case "FacebookShares": afr.FacebookShares = reader.ReadInt32(); break; case "TweetsCount": afr.TweetsCount = reader.ReadInt32(); break; case "BodyLength": afr.BodyLength = reader.ReadInt64(); break; case "ImageClusterId": afr.ImageClusterId = reader.ReadInt64(); break; case "VideoId": afr.VideoId = reader.ReadInt64(); break; } break; case BsonReaderState.ScopeDocument: break; case BsonReaderState.EndOfDocument: reader.ReadEndDocument(); return afr; case BsonReaderState.EndOfArray: reader.ReadEndArray(); break; case BsonReaderState.Done: return afr; case BsonReaderState.Closed: return afr; default: throw new ArgumentOutOfRangeException(); } } } return null; } } public class ArticleBase { private long articleId; [BsonId] public long ArticleId { get { return articleId; } set { articleId = value; ShardKey = (int)(value % 255); } } public int ShardKey { get; set; } public DateTime? Published { get; set; } } public class ArticleForRanking : ArticleBase { public long? MediaId { get; set; } public double? AggregatedRank { get; set; } public int? BigImagesCount { get; set; } public int? VideoCount { get; set; } public int? FacebookShares { get; set; } public int? TweetsCount { get; set; } public long? BodyLength { get; set; } public long? ImageClusterId { get; set; } public long? VideoId { get; set; } } }