title: NewtonSoft Json serializer performance
body: <p>I have an object that I am serializing into Json using NewtonSoft Json.Net. The object is relatively large, the resulting Json is about 300kb, but the serialization process takes around 60 seconds.</p>
  
  <p>The objects to be serialized are just plain POCO's.</p>
  
  <p>The code I am using is </p>
  
  <pre><code>string json = Newtonsoft.Json.JsonConvert.SerializeObject(data, Formatting.Indented);
  </code></pre>
  
  <p>Is there anything that can be done to speed up the serialization, adding attributes etc.</p>
  
  <p>EDIT: I have just tested with ServiceStack.Text Json serializer and that takes 48 seconds, still pretty slow.</p>
  
  <pre><code>[Serializable]
  public class AppointmentItemViewModel 
  {
      public AppointmentItemViewModel()
      {
          Data = new AppointmentData();
          Statuses = new List&lt;Status&gt;();
          ClosedDays = new List&lt;ClosedDay&gt;();
          OpenHours = new List&lt;OpenHours&gt;();
      }
  
      public int CurrentDay { get; set; }
  
      public int CurrentMonth { get; set; }
  
      public int CurrentYear { get; set; }
  
      public int Day { get; set; }
  
      public int Month { get; set; }
  
      public int Year { get; set; }
  
      public int FirstHour { get; set; }
  
      public int LastHour { get; set; }
  
      public int CurrentHour { get; set; }
  
      public int Step { get; set; }
  
      public bool StaffOnlyBookOwn { get; set; }
  
      public bool AllowPastAppointments { get; set; }
  
      public bool AllowBlocks { get; set; }
  
      public bool AllowGoogleCalendarSync { get; set; }
  
      public long CurrentUser { get; set; }
  
      public string DebugInfo { get; set; }
  
      public bool HasResources { get; set; }
  
      public string OrganisationId { get; set; }
  
      public string DefaultTab { get; set; }
  
      public string StartDay { get; set; }
  
      public bool AppointmentBreaksOnWeek { get; set; }
  
      public bool AppointmentBreaksOnMonth { get; set; }
  
      public AppointmentData Data { get; set; }
  
      public IEnumerable&lt;Status&gt; Statuses { get; set; }
  
      public IEnumerable&lt;LocationStaff&gt; Staff { get; set; }
  
      public IEnumerable&lt;ClosedDay&gt; ClosedDays { get; set; }
  
      public IEnumerable&lt;OpenHours&gt; OpenHours { get; set; }
  
      public IUserContext UserContext()
      {
          return ServiceLocator.Current.GetInstance&lt;IUserContext&gt;();
      }
  
      public override string ToString()
      {
          // Serialize the Json
          var sb = new StringBuilder();
  
          StringWriter sw = new StringWriter(sb);
  
          using (JsonWriter writer = new JsonTextWriter(sw))
          {
              writer.WriteStartObject();
  
              WriteProperty(writer, "CurrentDay", this.CurrentDay);
              WriteProperty(writer, "CurrentMonth", this.CurrentMonth);
              WriteProperty(writer, "CurrentYear", this.CurrentYear);
              WriteProperty(writer, "Day", this.Day);
              WriteProperty(writer, "Month", this.Month);
              WriteProperty(writer, "Year", this.Year);
              WriteProperty(writer, "FirstHour", this.FirstHour);
              WriteProperty(writer, "LastHour", this.LastHour);
              WriteProperty(writer, "CurrentHour", this.CurrentHour);
              WriteProperty(writer, "Step", this.Step);
              WriteProperty(writer, "StaffOnlyBookOwn", this.StaffOnlyBookOwn);
              WriteProperty(writer, "AllowPastAppointments", this.AllowPastAppointments);
              WriteProperty(writer, "AllowBlocks", this.AllowBlocks);
              WriteProperty(writer, "AllowGoogleCalendarSync", this.AllowGoogleCalendarSync);
              WriteProperty(writer, "CurrentUser", this.CurrentUser);
              WriteProperty(writer, "HasResources", this.HasResources);
              WriteProperty(writer, "OrganisationId", this.OrganisationId);
              WriteProperty(writer, "DefaultTab", this.DefaultTab);
              WriteProperty(writer, "StartDay", this.StartDay);
              WriteProperty(writer, "AppointmentBreaksOnWeek", this.AppointmentBreaksOnWeek);
              WriteProperty(writer, "AppointmentBreaksOnMonth", this.AppointmentBreaksOnMonth);
  
  
              writer.WritePropertyName("Statuses");
              writer.WriteStartArray();
              foreach (var item in this.Statuses)
              {
                  writer.WriteStartObject();
                  WriteProperty(writer, "Id", item.Id);
                  WriteProperty(writer, "Description", item.Description);
                  WriteProperty(writer, "Color", item.Color);
                  writer.WriteEndObject();
              }
              writer.WriteEndArray();
  
  
              writer.WritePropertyName("Staff");
              writer.WriteStartArray();
              foreach (var item in this.Staff)
              {
                  writer.WriteStartObject();
                  WriteProperty(writer, "Id", item.Id);
                  WriteProperty(writer, "Name", item.Name);
                  writer.WriteEndObject();
              }
              writer.WriteEndArray();
  
  
              writer.WritePropertyName("ClosedDays");
              writer.WriteStartArray();
              foreach (var item in this.ClosedDays)
              {
                  writer.WriteStartObject();
                  WriteProperty(writer, "Year", item.Year);
                  WriteProperty(writer, "Month", item.Month);
                  WriteProperty(writer, "Day", item.Day);
                  writer.WriteEndObject();
              }
              writer.WriteEndArray();
  
  
              writer.WritePropertyName("OpenHours");
              writer.WriteStartArray();
              foreach (var item in this.OpenHours)
              {
                  writer.WriteStartObject();
                  WriteProperty(writer, "DayOfWeek", item.DayOfWeek);
                  WriteProperty(writer, "OpenHour", item.OpenHour);
                  WriteProperty(writer, "CloseHour", item.CloseHour);
                  writer.WriteEndObject();
              }
              writer.WriteEndArray();
  
              // Main data
              writer.WritePropertyName("Data");
              writer.WriteStartObject();
  
              writer.WritePropertyName("Appointments");
              writer.WriteStartArray();
              foreach (var item in this.Data.Appointments)
              {
                  writer.WriteStartObject();
  
                  WriteProperty(writer, "Id", item.Id);
                  WriteProperty(writer, "AppointmentId", item.AppointmentId);
                  WriteProperty(writer, "Year", item.Year);
                  WriteProperty(writer, "Month", item.Month);
                  WriteProperty(writer, "Day", item.Day);
                  WriteProperty(writer, "StartHour", item.StartHour);
                  WriteProperty(writer, "StartMinute", item.StartMinute);
                  WriteProperty(writer, "EndHour", item.EndHour);
                  WriteProperty(writer, "EndMinute", item.EndMinute);
                  WriteProperty(writer, "ResourceId", item.ResourceId);
                  WriteProperty(writer, "Description", item.Description);
                  WriteProperty(writer, "Status", item.Status);
                  WriteProperty(writer, "IsClass", item.IsClass);
                  WriteProperty(writer, "ProcessingLength", item.ProcessingLength);
                  WriteProperty(writer, "ClientId", item.ClientId);
                  WriteProperty(writer, "ClientName", item.ClientName);
                  WriteProperty(writer, "ClientPhone", item.ClientPhone);
                  WriteProperty(writer, "ClientNotes", item.ClientNotes);
                  WriteProperty(writer, "ClientHasMobile", item.ClientHasMobile);
                  WriteProperty(writer, "ClassFull", item.ClassFull);
                  WriteProperty(writer, "ClientWaiting", item.ClientWaiting);
                  WriteProperty(writer, "PromotionCode", item.PromotionCode);
                  WriteProperty(writer, "ArrivalNote", item.ArrivalNote);
                  WriteProperty(writer, "Labels", item.Labels);
                  WriteProperty(writer, "ReminderSent", item.ReminderSent);
                  WriteProperty(writer, "Cancelled", item.Cancelled);
  
  
                  writer.WritePropertyName("Items");
                  writer.WriteStartArray();
                  foreach (var appointmentItem in item.Items)
                  {
                      writer.WriteStartObject();
                      WriteProperty(writer, "Name", appointmentItem.Name);
                      WriteProperty(writer, "Length", appointmentItem.Length);
                      WriteProperty(writer, "ProcessingTime", appointmentItem.ProcessingTime);
                      WriteProperty(writer, "Resource", appointmentItem.Resource);
                      writer.WriteEndObject();
                  }
                  writer.WriteEndArray();
  
                  writer.WriteEndObject();
              }
              writer.WriteEndArray();
  
              writer.WritePropertyName("Resources");
              writer.WriteStartArray();
              foreach (var item in this.Data.Resources)
              {
                  writer.WriteStartObject();
  
                  WriteProperty(writer, "Id", item.Id);
                  WriteProperty(writer, "Name", item.Name);
                  WriteProperty(writer, "BlockLength", item.BlockLength);
                  WriteProperty(writer, "StartHour", item.StartHour);
                  WriteProperty(writer, "EndHour", item.EndHour);
  
  
                  writer.WritePropertyName("Breaks");
                  writer.WriteStartArray();
                  foreach (var breakItem in item.Breaks)
                  {
                      writer.WriteStartObject();
                      WriteProperty(writer, "Year", breakItem.Year);
                      WriteProperty(writer, "Month", breakItem.Month);
                      WriteProperty(writer, "Day", breakItem.Day);
                      WriteProperty(writer, "DayOfWeek", breakItem.DayOfWeek);
                      WriteProperty(writer, "StartHour", breakItem.StartHour);
                      WriteProperty(writer, "StartMinute", breakItem.StartMinute);
                      WriteProperty(writer, "Length", breakItem.Length);
                      WriteProperty(writer, "Description", breakItem.Description);
                      WriteProperty(writer, "OtherBreak", breakItem.OtherBreak);
                      WriteProperty(writer, "UserBreak", breakItem.UserBreak);
                      writer.WriteEndObject();
                  }
                  writer.WriteEndArray();
  
  
                  writer.WritePropertyName("OpenCloseBreaks");
                  writer.WriteStartArray();
                  foreach (var breakItem in item.OpenCloseBreaks)
                  {
                      writer.WriteStartObject();
                      WriteProperty(writer, "Year", breakItem.Year);
                      WriteProperty(writer, "Month", breakItem.Month);
                      WriteProperty(writer, "Day", breakItem.Day);
                      WriteProperty(writer, "DayOfWeek", breakItem.DayOfWeek);
                      WriteProperty(writer, "StartHour", breakItem.StartHour);
                      WriteProperty(writer, "StartMinute", breakItem.StartMinute);
                      WriteProperty(writer, "Length", breakItem.Length);
                      WriteProperty(writer, "Description", breakItem.Description);
                      WriteProperty(writer, "OtherBreak", breakItem.OtherBreak);
                      WriteProperty(writer, "UserBreak", breakItem.UserBreak);
                      writer.WriteEndObject();
                  }
                  writer.WriteEndArray();
  
                  writer.WriteEndObject();
              }
              writer.WriteEndArray();
  
              writer.WriteEndObject();
          }
  
          return sb.ToString();
      }
  
      private void WriteProperty(JsonWriter writer, string name, object value)
      {
          writer.WritePropertyName(name);
  
          if (value == null)
          {
              writer.WriteNull();
          }
          else
          {
              writer.WriteValue(value);
          }
      }
  
  }
  
  [Serializable]
  public class AppointmentData
  {
      public IEnumerable&lt;ExternalEvent&gt; ExteralEvents { get; set; }
  
      public IEnumerable&lt;Appointment&gt; Appointments { get; set; }
  
      public IEnumerable&lt;Resource&gt; Resources { get; set; }
  }
  
  [Serializable]
  public class ClosedDay
  {
      public int Year { get; set; }
  
      public int Month { get; set; }
  
      public int Day { get; set; }
  }
  
  [Serializable]
  public class Appointment
  {
      public long Id { get; set; }
  
      public long AppointmentId { get; set; }
  
      public int Year { get; set; }
  
      public int Month { get; set; }
  
      public int Day { get; set; }
  
      public int StartHour { get; set; }
  
      public int StartMinute { get; set; }
  
      public int EndHour { get; set; }
  
      public int EndMinute { get; set; }
  
      public long ResourceId { get; set; }
  
      public string Description { get; set; }
  
      public long Status { get; set; }
  
      public bool IsClass { get; set; }
  
      public int ProcessingLength { get; set; }
  
  
      public long ClientId { get; set; }
  
      public string ClientName { get; set; }
  
      public string ClientPhone { get; set; }
  
      public string ClientNotes { get; set; }
  
      public bool ClientHasMobile { get; set; }
  
      public bool ClassFull { get; set; }
  
      public string ClientWaiting { get; set; }
  
      public string PromotionCode { get; set; }
  
      public string ArrivalNote { get; set; }
  
      public string Labels { get; set; }
  
      public bool ReminderSent { get; set; }
  
      public bool Cancelled { get; set; }
  
      public IEnumerable&lt;AppointmentItems&gt; Items { get; set; }
  }
  
  [Serializable]
  public class AppointmentItems
  {
      public string Name { get; set; }
  
      public int Length { get; set; }
  
      public int ProcessingTime { get; set; }
  
      public string Resource { get; set; }
  }
  
  [Serializable]
  public class OpenHours
  {
      public int DayOfWeek { get; set; }
  
      public int? OpenHour { get; set; }
  
      public int? CloseHour { get; set; }
  }
  
  [Serializable]
  public class Resource
  {
      public Resource()
      {
          Breaks = new List&lt;ResourceBreak&gt;();
          Blocks = new List&lt;ResourceBlock&gt;();
          OpenCloseBreaks = new List&lt;ResourceBreak&gt;();
      }
  
      public long Id { get; set; }
  
      public string Name { get; set; }
  
      public int BlockLength { get; set; }
  
      public int StartHour { get; set; }
  
      public int EndHour { get; set; }
  
      public IEnumerable&lt;ResourceBreak&gt; Breaks { get; set; }
  
      public IEnumerable&lt;ResourceBlock&gt; Blocks { get; set; }
  
      public IEnumerable&lt;ResourceBreak&gt; OpenCloseBreaks { get; set; }
  
  }
  
  [Serializable]
  public class ExternalEvent
  {
      public long Id { get; set; }
  
      public int Year { get; set; }
  
      public int Month { get; set; }
  
      public int Day { get; set; }
  
      public int DayOfWeek { get; set; }
  
      public int StartHour { get; set; }
  
      public int StartMinute { get; set; }
  
      public int EndHour { get; set; }
  
      public int EndMinute { get; set; }
  
      public int Length { get; set; }
  
      public string Description { get; set; }
  }
  
  [Serializable]
  public class ResourceBreak
  {
      public int Year { get; set; }
  
      public int Month { get; set; }
  
      public int Day { get; set; }
  
      public int DayOfWeek { get; set; }
  
      public int StartHour { get; set; }
  
      public int StartMinute { get; set; }
  
      public int Length { get; set; }
  
      public string Description { get; set; }
  
      public bool OtherBreak { get; set; }
  
      public bool UserBreak { get; set; }
  }
  
  [Serializable]
  public class ResourceBlock
  {
      public int StartHour { get; set; }
  
      public int StartMinute { get; set; }
  
      public int Length { get; set; }
  }
  
  [Serializable]
  public class Status
  {
      public long Id { get; set; }
  
      public string Description { get; set; }
  
      public int Color { get; set; }
  }
  
  [Serializable]
  public class LocationStaff
  {
      public long Id { get; set; }
  
      public string Name { get; set; }
  }
  </code></pre>