Firstly, a GFX shader program is never linked with a compute shader, hence, managing the GFX programs and the compute programs in two different lists eliminates the needless check for compute shaders when searching for GFX shaders. Secondly, shader IDs are 32 bit values, and since a shader program must consist of at least a vertex shader (VS) and a fragment shader (FS) to result in actual drawing, one can combine these two 32 bit values into one 64 bit value outside the LIST_FOR_EACH_ENTRY loop, and thereby save one comparison and one deref inside the loop. Then, by distributing the IDs over 2 n buckets of shader program lists one can further reduce the number of times the loop must be run to find a shader program or signal that a new program must be linked.