title: Dynamic heightForRowAtIndexPath: with many (thousands) of cells
body: <p>I'm having some performance issues when using a dynamic value in <code>heightForRowAtIndexPath:</code> 
   (I know it's this method because if I set a static value the responsiveness increases substantially). My table contains around 3000 cells.</p>
  
  <p>I understand why the performance suffers when using a dynamic value (mainly because the calculations in the method must be performed once for every cell in the table before the data can be shown), but I can't figure out how to make it more efficient.</p>
  
  <p>In many of the similar questions I've come across, the proposed solution was to use <code>NSString</code>'s <code>sizeWithFont</code> method in <code>heightForRowAtIndexPath:</code> to speed things up. I currently do that but the table still takes roughly ~1.5sec to load (and reload, which is done somewhat frequently). This is just too long and I need to optimize it.</p>
  
  <p>The code I'm currently using (the essence of it at least) is below:</p>
  
  <pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
      static NSString *CellIdentifier = @"Cell";
      UITableViewCell *cell;
      UILabel *label = nil;
  
      if (cell == nil) {
          cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  
          label = [[UILabel alloc] initWithFrame:CGRectZero];
          // set up label..
          [[cell contentView] addSubview:label];
  
      }
  
      NSDictionary *dict = alphabetDict; //dictionary of alphabet letters (A-Z). each key contains an NSArray as its object
      CGFloat rightMargin = 50.f; //padding for the tableview's index titles
  
      NSString *key = [[[dict allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section];
      NSArray *array = [dict objectForKey:key];
      NSString *cellText = [array objectAtIndex:indexPath.row];
  
      //TABLE_WIDTH is 268.f, CELL_MARGIN is 14.f
      CGSize constraintSize = CGSizeMake(TABLE_WIDTH - (CELL_MARGIN * 2) - rightMargin, 20000.0f);
      CGSize labelSize = [cellText sizeWithFont:[UIFont systemFontOfSize:17] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
      [label setFrame:CGRectMake(CELL_MARGIN, CELL_MARGIN, TABLE_WIDTH - (CELL_MARGIN * 2) - rightMargin, labelSize.height)];
      [label setText:cellText];
  
      return cell;
  }
  
  -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
  {
      //TODO make this faster
  
      NSDictionary *dict = alphabetDict;
      CGFloat rightMargin = 50.f;
  
      NSString *key = [[[dict allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section];
      NSArray *array = [dict objectForKey:key];
      NSString *cellText = [array objectAtIndex:indexPath.row];
  
      CGSize constraintSize = CGSizeMake(TABLE_WIDTH - (CELL_MARGIN * 2) - rightMargin, 20000.0f);
      CGSize labelSize = [cellText sizeWithFont:[UIFont systemFontOfSize:17] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
  
      return labelSize.height + (CELL_MARGIN * 2) + 16.f;  
  }
  </code></pre>
  
  <p>Could someone point me in the right direction to streamline this code further? Thanks!</p>