title: animating a large number of rows/sections in UITableView poor performance
body: <p>we're not talking thousands of rows or anything, although if there was a way to make things scale up that high, I'd love it.</p>
  
  <p>I have a table with 27 sections and 180 rows spread across all sections, and the scenario I'm currently getting stuck in is when I animate things to a model state with only 3 sections and 5 rows, and  (even worse) back again.</p>
  
  <p>I'm batching all the animations with beginUpdates/endUpdates.  My app pretty well locks up for 1-2 seconds on an iphone4 while it figures things out, then the animations start.</p>
  
  <p>I've tried both animating the removal/addition of each row, keeping the sections around (and dropping their row counts to 0 in the removal case), and also animating just the removal/insertions of the sections themselves (when the row count would have dropped to 0).  I would have assumed the latter would give better performance but it didn't change things at all.</p>
  
  <p>Is there anything that can be done on the app end to speed this up?  Right now I have a rather gross bit of code to bail out of the individual animations if there are more than 20 of them, opting to just reloadData instead.</p>
  
  <p><strong>edit</strong> here's code that exhibits the problem.  The performance of this code is slightly better than the equivalent monotouch code (which is what I was using before), but it's still pretty bad.</p>
  
  <pre><code>#import "TableViewController.h"
  
  @interface MyTableViewDataSource : NSObject&lt;UITableViewDataSource&gt; {
      int rows;
  };
  
  @end
  
  @implementation MyTableViewDataSource
  
  - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  {
      return 1;
  }
  
  - (void)setRowCount:(int)r
  {
      rows = r;
  }
  
  - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  {
      return rows;
  }
  
  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
      static NSString *CellIdentifier = @"Cell";
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      if (!cell)
          cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  
      cell.textLabel.text = [NSString stringWithFormat:@"row %d", indexPath.row];
  
      return cell;
  }
  
  @end
  
  @implementation MyTableViewController {
      UIBarButtonItem *populateButtonItem;
  };
  
  - (id)initWithStyle:(UITableViewStyle)style
  {
      self = [super initWithStyle:style];
      if (self) {
          populateButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Populate" style:UIBarButtonItemStylePlain target:self action:@selector(populateDataSource)];
      }
      return self;
  }
  
  - (void)populateDataSource
  {
      NSMutableArray* new_rows = [[NSMutableArray alloc] init];
      [((MyTableViewDataSource*)self.tableView.dataSource) setRowCount:200];
  
      for (int i = 0; i &lt; 200; i ++)
          [new_rows addObject:[NSIndexPath indexPathForRow:i inSection:0]];
  
      [self.tableView beginUpdates];
      [self.tableView insertRowsAtIndexPaths:new_rows withRowAnimation:UITableViewRowAnimationAutomatic];
      [self.tableView endUpdates];
  }
  
  - (void)viewDidLoad
  {
      [super viewDidLoad];
  
      self.tableView.dataSource = [[MyTableViewDataSource alloc] init];
      self.navigationItem.rightBarButtonItem = populateButtonItem;
  }
  
  @end
  </code></pre>