Не могли бы вы посмотреть, сколько изображений вы можете сгенерировать, если вы закомментируете следующую строку в вашем первом методе:
[imageData writeToFile:finalPath atomically:YES];
Причина, по которой я говорю, что вы собираетесь потратить много времени на запись этого образа на диск. Было бы интересно посмотреть, как это работает без записи изображений на диск. По крайней мере, таким образом вы будете знать, все ли время потрачено на создание образа, а не на его сохранение. Или вы можете сделать так, как упомянул другой плакат, и использовать инструменты, чтобы определить, как долго вы находитесь в каждом методе.
Если окажется, что запись изображений на диск занимает слишком много времени, тогда я предлагаю попробовать реализовать механизм кэширования, который будет кэшировать изображения в памяти и записывать их на диск позже.
Может также помочь попытаться вызвать writeToFile: atomically: в фоновом потоке.