﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	blockedby	blocking	notify_on_close	platform	project
1012	Methods for fast automatic object deletion	Tristan Croll	Eric Pettersen	"I have a working C++ dihedral implementation along with a manager that grows and shrinks as needed - either creating the dihedral objects all at once or just on demand, and deleting them when atoms/residues are deleted. Everything's fast, other than deletion. For example, for an 11,850 residue structure, the below test script gives:

Finding 58230 dihedrals for 11850 residues took 0.21404 seconds
Retrieving all 11800 omega dihedrals took 0.00186 seconds
Getting all dihedral angles for 11800 dihedrals took 0.00494 seconds
Deleting 11892 atoms in 748 residues took 6.56996 seconds

If I understand correctly, the reason for the slow deletion speed (~O(N^2^) in model size) is that my `Proper_Dihedral_Mgr` is a `DestructionObserver` (looking for deleted `Atom` and `Residue` instances and deleting `Proper_Dihedral` instances and mappings accordingly) - but the `Proper_Dihedral` deletions themselves create new `DestructionUser` instances. So everything gets a bit circular, and there's a lot of spinning of wheels until it sorts itself out.

It's not particularly urgent (only becomes problematic for large structures, when deleting large numbers of atoms at once), but it would be nice to find a way to improve on this. I'd like to suggest a minor modification to the destruction framework. What if, instead of `DestructionCoordinator` storing the destroyed pointers as `std::set<void*>`, it stored them as `std::unordered_map<std::type_index, std::set<void*> >` with the key being the original type of the destroyed pointers? Then each `DestructionObserver` could quickly determine if any of the destroyed pointers are of interest without having to loop through all of them. 


{{{
from chimerax.core.atomic import AtomicStructure
m = session.models.list(type=AtomicStructure)[0]
r = m.residues
from chimerax.isolde import molobject, molarray
dm = molobject.Proper_Dihedral_Mgr(session)
from time import time
start_time = time()
dm.find_dihedrals(m)
print ('Finding {} dihedrals for {} residues took {:.5f} seconds'.format(len(dm), len(r), time()-start_time))

start_time = time()
omegas = dm.get_dihedrals(r, 'omega')
print('Retrieving all {} omega dihedrals took {:.5f} seconds'.format(len(omegas), time()-start_time))

start_time = time()
angles = omegas.angles
print('Getting all dihedral angles for {} dihedrals took {:.5f} seconds'.format(len(omegas), time()-start_time))

chain_a = m.atoms[m.atoms.chain_ids == 'A']
n_atoms = len(chain_a)
n_res = len(chain_a.unique_residues)
start_time = time()
chain_a.delete()
print('Deleting {} atoms in {} residues took {:.5f} seconds'.format(n_atoms, n_res, time()-start_time))
}}}
"	enhancement	closed	moderate		Performance		not a bug		Tom Goddard				all	ChimeraX
