The Arduino always runs whatever code is programmed on it when it is powered on. When plugged into a PC, the only difference is that the USB-Serial chip on the board can be used to send and receive data to/from it, acting as a translator.
Only native USB devices such as the Arduino Leonardo communicate with the computer to tell it what kind of device it is (Keyboard, MIDI instrument etc.), so these are the only boards which "know" when they are communicating with a computer.
The other Arduinos send out data whenever Serial.print is called, without checking for any connection, like talking to a brick wall. So they execute every time.
Every Serial.print takes time, and for the somewhat classic 9600 baud rate, that means that sending 9600 characters would take about ten seconds, sending 960 would take a full second etc.; increasing the baud rate would take less time but it's still unnecessarily slower to print data when no one is listening.
If you are using a more common board like the UNO or Nano, a possible solution could be to have a global flag that only becomes true when something is received through serial and have all Serial.print instructions locked behind an if-statement.
bool is_Serial_open = false;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available()) {
is_Serial_open = true;
}
if (is_Serial_open) {
Serial.println("Serial opened");
}
}
The Serial.available() function returns how many bytes have been received through serial. If any are received, it will return a value greater than 0 and the if-statement will execute because it evaluates to "true".
This sketch does nothing until you send something through the serial monitor (a character, a newline, anything), after which the flag becomes true and the print statement executes in a loop.