Let me add a few remarks:
getSolution() is more powerful than getSlack(); while both can be called with (numerical) indices, constraint/variable objects, and constraint/variable names, both alone or in lists/arrays, getSolution() allows for more complex parameters such as expressions or lists thereof: one can call getSolution(x + x) or even getSolution([[x**1, x**2], [x**3, x**4]]), while the same can't happen for getSlack();
the above difference stems from more general function xpress.evaluate(), which evaluates any expression (e.g. a constraint's lhs or part of the objective) using a variable assignment that can be different than the current solution and/or a different problem object.
getSolution() is little more than a wrapper for xpress.evaluate();
other functions behave like getSlack(): these are getDual() and getRCost();
efficiency won't be much affected by calling getSlack() or getSolution() with a small subset: the Python
interface uses the C API functions for retrieving slack and solution, which however return the whole solution vector requested. The Python interface then takes care of selecting the right subset.
As stated in the Modeling chapter of the Python interface's reference manual, calling getSolution(x[i]) or getSlack(constrs[i]) several times will result in as many C API calls that return the whole vector. It is advisable instead to call these functions once.