Replace Every instances of an object by a 2.79duppligroup / 2.8CollectionInstance?doing this trough python?
here'sa code that do that .. the api may change in the future
i tested on 300 instances of suzannes its working great 

theres just a missing part at the end of the code, i need to hide "newcoll", my original object of every instances from displaying in render, because the obj need to stay in X=0 Y=0 Z=0



import bpy

#Copy and past for later move to newcoll code
context = bpy.context
scene = context.scene
debut = context.object

def find_collection(context, item):
    collections = item.users_collection
    if len(collections) &gt; 0:
        return collections[0]
    return context.scene.collection

def make_collection(collection_name, parent_collection):
    if collection_name in bpy.data.collections:
        return bpy.data.collections[collection_name]
    else:
        new_collection = bpy.data.collections.new(collection_name)
        parent_collection.children.link(new_collection)
        return new_collection

#naming preference of created layer system 
pref = "%s Instancer " % debut.name
name = "%s" % (pref)



#nomme first select asset as basic, dupplicate it, name new newcoll, reset loc,rot,sca on newcoll
basic = bpy.context.object
bpy.ops.object.duplicate_move_linked(OBJECT_OT_duplicate={"linked":True, "mode":'TRANSLATION'})
newcoll = bpy.context.object
newcoll.location[0] = 0
newcoll.location[1] = 0
newcoll.location[2] = 0
newcoll.rotation_euler[0] = 0
newcoll.rotation_euler[1] = 0
newcoll.rotation_euler[2] = 0
newcoll.scale[0] = 1
newcoll.scale[1] = 1
newcoll.scale[2] = 1

#move newcoll dans collection appart
newcoll_collection = find_collection(bpy.context, newcoll)
new_collection = make_collection(name , newcoll_collection)
new_collection.objects.link(newcoll)
newcoll_collection.objects.unlink(newcoll)

#create a temporary instance, first create empty...
bpy.ops.object.empty_add(type='PLAIN_AXES', view_align=False, location= cursor)
bpy.context.object.name = "%s Instance " % debut.name
bpy.context.object.instance_type = 'COLLECTION'
bpy.context.object.instance_collection = bpy.data.collections[name]

instance = bpy.context.selected_objects[0]
instance.select_set(state=False)
newcoll.select_set(state=False)
debut.select_set(state=True)
bpy.context.view_layer.objects.active = debut

#selectionne tout instances sauf temporary instance, and newcoll
bpy.ops.object.select_linked(type='OBDATA')
newcoll.select_set(state=False)
instance.select_set(state=False)

#for every obj in selection, create an empty, copy collection of obj,create instance collection, then delete obj to enterely replace selection by empty 
for obj in bpy.context.selected_objects :
    bpy.ops.object.empty_add(type='PLAIN_AXES', view_align=False, location= obj.location, rotation = obj.rotation_euler)
    bpy.context.object.name = "%s Instance " % newcoll.name
    empty = bpy.context.view_layer.objects.active
    empty.select_set(state=False)
    obj.select_set(state=True)
    bpy.context.view_layer.objects.active = obj
    empty.select_set(state=True)
    bpy.ops.object.make_links_data(type='GROUPS')
    empty.scale = obj.scale
    empty.instance_type = 'COLLECTION'
    empty.instance_collection = instance.instance_collection
    bpy.context.object.show_instancer_for_viewport = False

    bpy.data.objects.remove(obj, do_unlink=True)

#Delete temporary instances
bpy.data.objects.remove(instance, do_unlink=True)