This is one way to do it without having to depend on bpy.ops
.
import bpy
name = "Cube"
size = 2
location = (0, 0, 0)
color = (0, 0, 1, 1)
# Generate the vertices and faces, edges are inferred from the polygons
s = size / 2
vertices = [(s, s, s),
(s, s, -s),
(s, -s, s),
(s, -s, -s),
(-s, s, s),
(-s, s, -s),
(-s, -s, s),
(-s, -s, -s)]
faces = [(0, 2, 3, 1), (0, 1, 5, 4), (2, 0, 4, 6), (1, 3, 7, 5), (3, 2, 6, 7), (4, 5, 7, 6)]
# Create a new mesh and set generated data
mesh = bpy.data.meshes.new(name)
mesh.from_pydata(vertices, [], faces)
# Create a new material
material = bpy.data.materials.new(f"{name}Mat")
# Mark the material to use nodes and set the base color of the Principled shader and the display color
material.use_nodes = True
material.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = color
material.diffuse_color = color
# Assign the material to the mesh
mesh.materials.append(material)
# Create a new object to hold the mesh and set its location
object = bpy.data.objects.new(name, mesh)
object.location = location
# Link the object to the active collection to be able to see it in the scene
bpy.context.collection.objects.link(object)
Running this 1000 times using a for loop takes about 0.0702 seconds on my PC. Running the first solution in X Y
's answer takes about 0.0941 seconds. Running the second solution in X Y
's answer takes about 0.2027 seconds. Running the selected answer here for 1000 cubes takes about 0.0324 seconds. Tests were run in Blender 4.0.
Edit 1: If the mesh can be shared between the objects, the proposed answer can take around 0.0132 seconds to generate 1000 objects that use the same mesh data.
Edit 2: I added a few extra steps to create and assign a material to the generated mesh.