They are basically exactly the same. If you look at the replacement source code, you will see:
function (x, list, values) { x[list] <- values x } <environment: namespace:base>
Thus, a replacement is nothing but a wrapper around [<- :
> replace(x.tst, s.tst==1, 0) [,1] [,2] [,3] [1,] 0 0 5 [2,] 0 4 6
Using [<- can give you speedup if you need to do this a million times, since you lose the extra call to the wrapper function. But it is truly marginal, so it is a matter of choice. I would say replace() bit readable
Btw, x.tst[s.tst==1] <- 0 is more readable than "[<-"(x.tst, s.tst==1, 0) . There is no reason to use this construct if you do not want to save the result in a new data area.
To clarify, as @Andrie pointed out, both with replace() and "[<-"(x.tst, s.tst==1, 0) , you get a copy of all x.tst with the changed values. So you can put this in a new object. This contradicts x.tst[s.tst==1] <- 0 , where you change the values ββin x.tst itself. Keep in mind that it does not save memory, since R will make an internal copy of x.tst before doing the manipulations.
Sync Results:
> system.time(replicate(1e6, replace(x.tst, s.tst==1, 0))) user system elapsed 12.73 0.03 12.78 > system.time(replicate(1e6, "[<-"(x.tst, s.tst==1, 0))) user system elapsed 6.42 0.02 6.44 > system.time(replicate(1e6, x.tst[s.tst==1] <- 0)) user system elapsed 5.28 0.02 5.32