RM, I'm getting an error on your SS- function "; error: bad argument type: lselsetp nil". Though your ss+ works fine on the same arguments. Also you're reusing an argument as the selection set to be created. Please note that the ssadd will actually modify the original selection set if used this way.
Anyhow, I've made 2 other versions. The first one is extremely simple:
Add two selection sets together using simplest possible method.
Code:
(defun ss-union (ss1 ss2 / ss n)
(setq n (sslength ss1)
ss (ssadd))
(while (>= (setq n (1- n)) 0) (ssadd (ssname ss1 n) ss))
(setq n (sslength ss2))
(while (>= (setq n (1- n)) 0) (ssadd (ssname ss2 n) ss))
ss)
Or the alternative method converting to lists first:
Code:
(defun ss-union2 (ss1 ss2 / ss)
(setq ss (ssadd))
(foreach e (list-union (ss->list ss1) (ss->list ss2)) (ssadd e ss))
ss)
(defun ss->list (ss / n lst)
(setq n (sslength ss))
(while (>= (setq n (1- n)) 0) (setq lst (cons (ssname ss n) lst)))
lst)
(defun list-subtract (lst1 lst2 / )
(vl-remove-if (function (lambda (item) (vl-position item lst2))) lst1))
(defun list-union (lst1 lst2 / )
(append lst1 (list-subtract lst2 lst1)))
The list conversion seems to work the fastest here:
Code:
Benchmarking .........Elapsed milliseconds / relative speed for 64 iteration(s):
(SS-UNION2 S1 S2)......1357 / 1.37 <fastest>
(SS+ S1 S2)............1436 / 1.29
(SS=SS1+SS2 S1 S2).....1840 / 1.01
(SS-UNION S1 S2).......1857 / 1 <slowest>
On the subtraction I'm doing a half-n-half idea first:
Code:
(defun ss-subtract (ss1 ss2 / ss n e elst)
(setq elst (ss->list ss2)
n (sslength ss1)
ss (ssadd))
(while (>= (setq n (1- n)) 0)
(if (not (vl-position (setq e (ssname ss1 n)) elst))
(ssadd e ss)))
ss)
And then the full convert to list:
Code:
(defun ss-subtract2 (ss1 ss2 / ss)
(setq ss (ssadd))
(foreach e (list-subtract (ss->list ss1) (ss->list ss2)) (ssadd e ss))
ss)
Here both perform a lot faster than marko's. I can't test against yours - as there's the a fore mentioned error. Still converting both selection sets to lists and then using my list-subtract works fastest.
Code:
Benchmarking ..........Elapsed milliseconds / relative speed for 128 iteration(s):
(SS-SUBTRACT2 S1 S2).....1092 / 3.74 <fastest>
(SS-SUBTRACT S1 S2)......1154 / 3.54
(SS=SS1-SS2 S1 S2).......4087 / 1 <slowest>
Also since yours would modify the SS1 argument itself, this would affect the test from the 2nd iteration.