v1 = RandomChoice[{-1, 1}, 100]; v2 = RandomChoice[{-1, 1}, 100]; vL = UnitStep[v1]; vL*v1 + (1 - vL)*v2
Using PatoCriollo's comparison (and now updated to include rasher and Mr. Wizard's methods):
n = 10^6; v1 = RandomChoice[{-1, 1}, n]; v2 = RandomChoice[{-1, 1}, n]; (bp = Boole[Positive[v1]]; test1 = bp v1 + (1 - bp) v2); // Timing test2 = With[{c = Clip[v1, {0, 0}, {0, 1}]}, c (v1 - v2) + v2]; // Timing test3 = Table[If[Positive[v1[[i]]], v1[[i]], v2[[i]]], {i, Length@v1}]; // Timing (vL = UnitStep[v1]; test4 = vL*v1 + (1 - vL)*v2;) // Timing (vL = UnitStep[v1]; test5 = vL (v1 - v2) + v2;) // Timing (vL = UnitStep[v1]; test6 = vL Subtract[v1, v2] + v2;) // Timing (pos = SparseArray[UnitStep[-v1]]["AdjacencyLists"]; test7 = v1; test7[[pos]] = v2[[pos]];) // Timing {0.479009, Null} {0.185765, Null} {0.192930, Null} {0.100705, Null} {0.102183, Null} {0.078348, Null} {0.087175, Null} test1 == test2 == test3 == test4 == test5 == test6 == test7 True
To summarize: the UnitStep method seems the fastest, the Clip and Table methods are about the same, while Boole takes up the rear. All the methods give the same answer. Interestingly, when we change RandomChoice to RandomReal, the Clip and the UnitStep methods are about the same speed (and both are faster than Table and Boole). Using Simon's trick of substituting Subtract[v1,v2] for v1-v2 also speeds up the UnitStep calculations by a modest, but measurable amount. Mr. Wizard's sparse array approach seems to be competitive with, but slightly slower than the UnitStep.
vN=Boole[Negative[v1]];$\endgroup$Positive@0 == Negative@0 == False$\endgroup$TrueandFalse. To get optimal performance from Mathematica you need to use homogeneous numerical arrays, which can be packed. Arrays with symbols in them ... $\endgroup$