The damage falloff right now just modifies velocity every 4 tiles of distance flown by something below 1 (or above 1 if your making a rocket or something). Its a bit crude and I might replace that with table that stores per-projectile properties (also handy for smoke, on-impact effects and preventing dumb stuff like smoke being triggered on bullets dropping after they ran out of reach), but it does work nicely for making gunpowder smallarms only go through armor at closer ranges, which was what they were known to do in the middle ages.
I'm actually putting in a table using your example ATM to store different smoke amounts, I haven't put the unique effects in yet, as I was worried about too many table lookups. It looks messier just doing weapon-type checks for weapon-specific function calls in onProjItemCheckMovement, but I think it might be nicer on performance. I'm using the weaponProperties table with indexes to avoid slower string hash lookups too, but again, messier.
Have you noticed any impact on performance storing more stuff in tables? I might just have to bite the bullet (npi), listen to thefriendlyhacker's reminder about writing to disk and get everything into a table if I'm able.
Dropping items from a height would in theory work and tried what your suggested, but the item only gets removed from the building holder list once it starts dropping, which is at least 1 tick so you would have to teleport it, use a timeout to wait for it to actually start dropping and then teleport it where you need it. Small bonus might be that it will already be a projectile at that point, so you might only have to change origin/target positions. Its... both kinda janky, so take your preferred pick 
I should mention that moveToGround and then immediately moving it to container worked at some point when I set the move coords to 5,5,5 but it only worked on one map and I havn't been able to reproduce that. It was weird.
Damn. That's disappointing. I'll have to keep messing about, I'll be sure to let you know if I come across anything.
The way I'm having the reactions go faster now is by adding every initiated artillery job to a table, checking job.completion_timer every 50 ticks, doing nothing if its -1 (default state if no dwarf is working the job yet), to 80 if no target is found and to 0 if one is found as well as dropping the job from the table. Using completion_timer seems to have no downsides and doesn't have issues like gunners gaining skill from having commands cancelled, dwarves finding no targets will just wait for something to blast until the job is cancelled or presumably until the dwarf gets sick of it due to starvation/etc. The only issue I'm having is that the script seems to have trouble identifying a firer every now and then.
I should also add that onJobInitiated triggers once the player orders up the job, immediately checking for a firer to modify results in the script borking because it doesn't have a firer yet.
Doy, of course there is a counter for it.

It's nice that the unit stands ready too, would make the idea of a fixed machine gun possible. Could set the timer to a given point above zero (accounting for normal tick-down) corresponding to ammo remaining in the gun and decrement the counter for each bullet fired so the unit doesn't complete the reaction until the gun is empty (or he gets hungry as you say). Looking forward to getting my meathooks on your code and seeing your implementation, I like how thoroughly you think through these things.
I also have had some strangeness with missing firers, it can usually just be checked for and ignored for infantry weapon projectiles (as I'm sure you know), but it's definitely more of an issue for cannon reactions.
The only thing I can offer to help is upon failing to find a firer with the usual check, maybe grab all units in the workshop with dfhack.getUnitsInBox() when the timer starts (assuming the timer stays at -1 until the work actually starts) and checking their profession to ensure you have got the firer and not a kitty, might not be too useful if you need the firer straight away, though.
If that timer works as I think it does, it could give a much-needed modicum of control between a job starting and finishing. Thanks for sharing and being so open, I really owe you one.
The trick I'm using right now for artillery dwarves getting spooked and running off is kinda dumb to be honest, I just make the front facing workshop tiles non-passable. It makes some amount of sense for medieval guns which were often placed behind wooden barricades, what with them often being set up in range of crossbows and other small weapons. I've not really tested it extensively though, my reserve solution was making the operator blind. Can't be spooked by things you can't see and blind dwarves don't really seem impeded in doing jobs. NOFEAR might work too, though it might result in typical dwarf behaviour of leaving the gun to charge and hit them with a sock.
I did consider that method when I read your post, I'm guessing from what you say it causes no problems for the projectile. I'd also be concerned about loading under fire though, I think I'll have to test out some syndromes.
Removing sight is a fine idea, you might have to employ a timeout eyeball de-pluck for abandoned job cases, mind. That's the strangest sentence I've written today.