tachometer, review of methods

We debounce dirty signals like contact switches closing and opening (tiny sparks) which you won't get with reflected IR.

The OP's problem is not due to the nature of the reflected IR but with the behavior of the lm 393 comparator ( used in the circuit without feedback )which is processing the signal from the IR receiver photo transistor.

The constant detachment and reattchment of the interrupt is not correct. Attach it only once in setup and use the noInterrupts() and interrupts() calls to pull unchanging data from the isr.

Here is a cleaner form of the code to read a period of time for a number of pulses.

volatile byte  count = 0;
byte numCount = 50;

volatile unsigned long startTime;
volatile unsigned long endTime;
unsigned long copy_startTime;
unsigned long copy_endTime;

volatile boolean finishCount = false;
float period;

unsigned int rpm = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println("start...");

  attachInterrupt(digitalPinToInterrupt(3), isrCount, FALLING);//interrupt on pin3
}

void loop()
{
  if (finishCount == true)
  {
    finishCount = false;//reset flag
    // disable interrupts, make protected copy of time values
    noInterrupts();
    copy_startTime = startTime;
    copy_endTime = endTime;
    interrupts();

    period = (copy_endTime - copy_startTime) / 1000.0;//micros to millis
    Serial.println(period);//debug
   

    rpm = numCount * 30.0 * (1000.0 / period);//two ccounts per revolution

    Serial.print("RPM = ");
    Serial.println(rpm);
  }
}

void isrCount()
{
  count++;

  if (count == 1)//increments on first entry to isr
  {
    startTime = micros();
  }

  if (count == numCount)
  {
    endTime = micros();
    finishCount = true;
    count = 0;
  }
}