Strategies for performing lots of world coordinate calculations in Blender
You should cache the result of the inner loop.

verts2 = [mat2 * ob2.data.vertices[v2_ind].co for v2_ind in verts2]


and might do this for the outer loop as well

verts1 = [mat1 * ob1.data.vertices[v1_ind].co for v1_ind in verts1]


Generally you might gain performance by keeping python objects rather than doing an attribute / index lookup each time.

Tested with suzanne subdivided 3 times:

import bpy
import timeit
log = bpy.data.texts['log']
log.clear()

stmt_setup = """
import bpy
obj = bpy.context.active_object
vertices = obj.data.vertices
mat_world = obj.matrix_world
indices = range(len(vertices))"""

stmt_vertex_iter = """
verts_world = [mat_world * v.co for v in vertices]"""

stmt_index_lu = """
verts_world = [mat_world * obj.data.vertices[i].co for i in indices]"""

time_lc = timeit.timeit(stmt=stmt_vertex_iter, setup=stmt_setup, number=100)
time_il = timeit.timeit(stmt=stmt_index_lu,    setup=stmt_setup, number=100)

log.write("Vertex Iterator %.4f \n" % time_lc)
log.write("Index Look Up %.4f \n" % time_il)


yields

Vertex Iterator 2.5746 
Index Look Up 4.8094