The most efficient method of updating vertex data would be to do it on the GPU. To do this you can use transform feedback. Transform feedback works by letting you write out changes to your vertices in the vertex shader back to your vertex buffer.
Or if you need to calculate the positions cpu side for some reason, glMapBufferRange may be the next best thing. I'm assuming at the moment you are doing something along the lines of:
GLuint myVBO; glm::vec3 positions[10000]; glm::vec3 colours[10000]; glGenBuffers(1, &myVBO); //Update for(...) position[i]+=velocity[i]; // Upload glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3)*10000, &positions[0], GL_DYNAMIC_DRAW); // Render
Instead you can do:
// (Not complete code) GLuint myVBO; glGenBuffers(1, &myVBO); glm::vec3 positions[10000]; glm::vec3 colours[10000]; // Set initial positions glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3)*10000, &positions[0], GL_DYNAMIC_DRAW); //Update glm::vec3 * gpuPositions = glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(glm::vec3)*10000, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); for(...) gpuPositions[i]+=velocity[i]; glUnmapBuffer(GL_ARRAY_BUFFER); // Render
These are OpenGL es 3.0 features. So may not be available on your device. If you need es 2.0, you are not going to get much more speed than uploading with glBufferData() each frame. If you are doing something along the lines of:
for(...) interleavedArray[i] = positions[i]; interleavedArray[i+3] = colours[i];
Then yes it would be more efficient to store the data already interleaved like:
for(...) interleavedArray[i+positionOffset] += velocity[i];