Because I was not sure if my extensive code (THREEf.js) has influence on the test, I have made a very simple example. Except for the differences between Geometry and BufferGeometry, the code is the same.

Try out
http://sandbox.threejs.hofk.de/Geometry_BufferGeometry/speedtestSimple.html
But again, Geometry is faster.
Memory consumption and speed are usually in the reverse ratio.
So if Geometry is omitted, then you have to use even more complicated things than BufferGeometry instead of simpler Geometry (to get speed)?
If Geometry is eliminated, it will be much harder for beginners to enter three.js. Many simple examples currently use Geometry. I understand, however, that the focus is on the professional programmers.
I can not fully understand the internals of three.js, maybe there is a way to solve the speed problem?
The code:
segments
<input type="text" size="5" id="hs" value="100" > x
<input type="text" size="5" id="rs" value="100" > :
<input type="radio" name="geom" id="Geometry" checked="checked" > Geometry
<input type="radio" name="geom" id="BufferGeometry" > indexed BufferGeometry
<input type="radio" name="color" id="multicolor" checked="checked" > multicolor
<input type="radio" name="color" id="monochrome" > monochrome
<button type="button" id="show"> -> show new mesh </button>
script src=“three.min.86.js”
script src=“OrbitControls.js”
script src=“THREEx.WindowResize.js”
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 200000 );
camera.position.set( 400, 600, 1000 );
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xeeeeee, 1 );
var container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
THREEx.WindowResize( renderer, camera );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableZoom = true;
var clock = new THREE.Clock( true );
var t; // time
var g; // Geometry or BufferGeometry
var mesh;
var hs; // height segment count ( y direction)
var rs; // radial segment count (here in test x direction)
var hss; // hs + 1
var rss; // rs + 1
var vertexCount;
var vIdx; // vertex Index
var faceCount;
var fIdx; // face index
var j0, j1; // j index
var a, b1, c1, c2; // vertex indices, b2 equals c1
var ni, nj; // relative counter variable
var posIdx; // position Index
var x, y, z; // position coordinates
var materialSegment;
var multicolor = null;;
var showGeo = false;
// materials
var uvTex = new THREE.TextureLoader().load( "uvgrid01.png" );
var waterlilyTex = new THREE.TextureLoader().load( "waterlily.png" );
// var earthTex = new THREE.TextureLoader().load( "earth_nasa_map_900.png" );
var side = THREE.DoubleSide;
var materials = [
// material index:
new THREE.MeshBasicMaterial( { color: 0x000000,transparent: true, opacity: 0.6, side: side } ), // 0 transparent
new THREE.MeshBasicMaterial( { map: uvTex, side: side } ), // 1 uv grid
new THREE.MeshPhongMaterial( { color: 0xff0000, emissive: 0xff0000, side: side } ), // 2 red
new THREE.MeshPhongMaterial( { color: 0x00ff00, emissive: 0x00ff00, side: side } ), // 3 green
new THREE.MeshPhongMaterial( { color: 0x0000ff, emissive: 0x0000ff, side: side } ), // 4 blue
new THREE.MeshPhongMaterial( { color: 0xffff00, emissive: 0xffff00, side: side } ), // 5 yellow
new THREE.MeshPhongMaterial( { color: 0xff00ff, emissive: 0xff00ff, side: side } ), // 6 mgenta
new THREE.MeshPhongMaterial( { color: 0x00ffff, emissive: 0x00ffff, side: side } ), // 7 cyan
new THREE.MeshBasicMaterial( { map: waterlilyTex, side: side } ), // 8 photo waterlily (free)
new THREE.MeshPhongMaterial( { color: 0x7755ff, emissive: 0x4433dd, side: side } ), // 9 color
new THREE.MeshPhongMaterial( { color: 0x444444, emissive: 0x333333, side: side } ) // 10 grey
];
// var material = new THREE.MeshBasicMaterial( { color: 0x880088, side: side, wireframe: true } );
// var material = new THREE.MeshBasicMaterial( { map: earthTex, side: side } );
document.getElementById( "show" ).onclick = showNewMesh;
animate();
function showNewMesh() {
if ( mesh ) {
scene.remove( mesh );
g.dispose();
showGeo = false;
multicolor = null;
}
hs = Math.floor( document.getElementById( "hs" ).value );
rs = Math.floor( document.getElementById( "rs" ).value );
hss = hs + 1;
rss = rs + 1;
vertexCount = hss * rss;
faceCount = hs * rs * 2;
multicolor = document.getElementById( "multicolor" ).checked;
// Geometry or BufferGeometry
if ( document.getElementById( "Geometry" ).checked ) g = new THREE.Geometry();
if ( document.getElementById( "BufferGeometry" ).checked ) g = new THREE.BufferGeometry();
// mesh
mesh = new THREE.Mesh( g, materials );
scene.add( mesh );
//configure
if ( g.isGeometry ) {
for ( var i = 0; i < vertexCount; i ++ ) {
g.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
}
}
if ( g.isBufferGeometry ) {
var idxCount = 0;
g.faceIndices = new Uint32Array( faceCount * 3 );
g.vertices = new Float32Array( vertexCount * 3 );
g.setIndex( new THREE.BufferAttribute( g.faceIndices, 1 ) );
g.addAttribute( 'position', new THREE.BufferAttribute( g.vertices, 3 ).setDynamic( true ) );
for ( var f = 0, p = 0; f < faceCount; f ++, p += 3 ) {
g.addGroup( p, 3, 0 ); // write group for multi material
}
}
for ( var j = 0; j < rs; j ++ ) {
j0 = hss * j;
j1 = hss * ( j + 1 );
for ( var i = 0; i < hs; i ++ ) {
// 2 faces / segment, 3 vertex indices
a = j0 + i;
b1 = j1 + i; // right-bottom
c1 = j1 + 1 + i;
// b2 = j1 + 1 + i; =c1 // left-top
c2 = j0 + 1 + i;
if ( g.isGeometry ) {
g.faces.push( new THREE.Face3( a, b1, c1 ) ); // right-bottom
g.faces.push( new THREE.Face3( a, c1, c2 ) ); // left-top
}
if ( g.isBufferGeometry ) {
g.faceIndices[ idxCount ] = a; // right-bottom
g.faceIndices[ idxCount + 1 ] = b1;
g.faceIndices[ idxCount + 2 ] = c1;
g.faceIndices[ idxCount + 3 ] = a; // left-top
g.faceIndices[ idxCount + 4 ] = c1,
g.faceIndices[ idxCount + 5 ] = c2;
idxCount += 6;
}
}
}
showGeo = true; // start animation
}
function move( t ) {
if ( g.isGeometry ) g.verticesNeedUpdate = true;
if ( g.isBufferGeometry ) g.attributes.position.needsUpdate = true;
for ( var j = 0; j < rss; j ++ ) {
nj = j / rs;
y = 400 * nj; // calculate y
for ( var i = 0; i < hss; i ++ ) {
ni = i / hs;
x = 400 * ni; // calculate x
z = 400 * Math.sin( t + ni + nj ); // calculate z
vIdx = hss * j + i;
if ( g.isGeometry ) g.vertices[ vIdx ].set( x, y, z );
if ( g.isBufferGeometry ) {
posIdx = vIdx * 3;
g.vertices[ posIdx ] = x;
g.vertices[ posIdx + 1 ] = y;
g.vertices[ posIdx + 2 ] = z;
}
}
}
if ( multicolor ) {
g.groupsNeedUpdate = true; // to change materialIndex for multi material
for ( var j = 0; j < rs ; j ++ ) {
for ( var i = 0; i < hs; i ++ ) {
materialSegment = Math.floor( 5 * ( 1 + Math.cos( 0.2 * t + i * i + 2 * j ) ) ); // calculate material
fIdx = 2 * hs * j + 2 * i;
if ( g.isGeometry ) {
g.faces[ fIdx ].materialIndex = materialSegment;
g.faces[ fIdx + 1 ].materialIndex = materialSegment;
}
if ( g.isBufferGeometry ) {
g.groups[ fIdx ].materialIndex = materialSegment;
g.groups[ fIdx + 1 ].materialIndex = materialSegment;
}
}
}
}
}
function animate() {
requestAnimationFrame( animate );
t = clock.getElapsedTime();
if ( showGeo ) move( t );
renderer.render( scene, camera );
controls.update();
}