Я согласен с Санчо, что Cython, вероятно, будет подходить, но вот пара небольших ускорений:
A. Сохраните grid[y, orig_x]
в некоторой переменной перед запуском цикла while и используйте эту переменную. Это сэкономит кучу обращений к массиву сетки.
B. Поскольку вы в основном начинаете с x_len - 1 в shadow_map и работаете до 1, вы можете избежать использования модуля очень часто. В основном, изменить:
while x != orig_x:
height_needed = shadow_map[( (x - orig_x) % x_len)]
до
for i in xrange(x_len-1,0,-1):
height_needed = shadow_map[i]
или просто избавьтесь от переменной height_needed вместе с:
if grid[y, x] - grid[y, orig_x] >= shadow_map[i]:
Это небольшие изменения, но они могут немного помочь.
Кроме того, если вы планируете идти по маршруту Cython, я бы подумал, чтобы ваша функция выполняла этот процесс для всей сетки или, по крайней мере, для строки за раз. Это сэкономит много накладных расходов при вызове функции. Однако вы не сможете сделать это в зависимости от того, как вы используете результаты.
Наконец, вы пытались использовать Psyco ? Это займет меньше работы, чем Cython, хотя, вероятно, это не даст вам такой большой прирост скорости. Я бы сначала попробовал.