Будет ли компилятор C ++ встроить цикл for с небольшим количеством терминов?

Command::new - это действительно путь, но он предназначен для выполнения программы. ls ; sleep 1; ls не является программой, это инструкции для некоторой оболочки. Если вы хотите выполнить что-то подобное, вам нужно попросить оболочку интерпретировать это для вас:

Command::new("/usr/bin/sh").args(&["-c", "ls ; sleep 1; ls"])
// your complex command is just an argument for the shell

Чтобы получить выход, существует два способа:

  • метод output блокирует и возвращает выходы и статус выхода команды.
  • метод spawn блокировки и возвращает дескриптор, содержащий дочерний процесс stdin, stdout и stderr, чтобы вы могли общаться с дочерним элементом, и метод wait , чтобы дождаться его завершения. Обратите внимание, что по умолчанию дочерний элемент наследует свой родительский дескриптор файла, и вы можете вместо этого настроить каналы:

Вы должны использовать что-то вроде:

let child = Command::new("/usr/bin/sh")
                .args(&["-c", "ls  sleep 1 ls"])
                .stderr(std::process::Stdio::null()) // don't care about stderr
                .stdout(std::process::Stdio::piped()) // set up stdout so we can read it
                .stdin(std::process::Stdio::piped()) // set up stdin so we can write on it
                .spawn().expect("Could not run the command"); // finally run the command

write_something_on(child.stdin);
read(child.stdout);

-2
задан melpomene 30 March 2019 в 22:37
поделиться

2 ответа

Да! GCC делает это на уровне оптимизации -O1 и выше, а clang делает это на уровне оптимизации -O2 и выше.

Я протестировал его, используя этот код:

struct Matrix5x5 {
    double values[5][5];
    Matrix5x5() : values() {}

    double trace() {
        double sum = 0.0;
        for(int i = 0; i < 5; i++) {
            sum += values[i][i]; 
        }
        return sum; 
    }
};

double trace_of(Matrix5x5& m) {
    return m.trace(); 
}

И это сборка, созданная как gcc, так и clang:

trace_of(Matrix5x5&):
    pxor    xmm0, xmm0
    addsd   xmm0, QWORD PTR [rdi]
    addsd   xmm0, QWORD PTR [rdi+48]
    addsd   xmm0, QWORD PTR [rdi+96]
    addsd   xmm0, QWORD PTR [rdi+144]
    addsd   xmm0, QWORD PTR [rdi+192]
    ret

Вы можете поиграться с кодом и посмотрите соответствующую сборку здесь: https://godbolt.org/z/p2uF0E .

Если вы перегрузите operator[], то вам придется повысить уровень оптимизации до -O3, но компилятор все равно сделает это: https://godbolt.org/z/JInIME [117 ] [+1112]

0
ответ дан J. Antonio Perez 30 March 2019 в 22:37
поделиться

Если ваш компилятор достаточно умен, он может оптимизировать этот случай с помощью как-будто правила . Таким образом, компилятор C ++ может оптимизировать многие вещи. Но это также не может. Единственный способ быть абсолютно уверенным - это проверить код, сгенерированный вашим конкретным компилятором. При этом вряд ли это станет узким местом в вашей программе. Так что делайте, какая версия будет более читабельной.

0
ответ дан Ayxan 30 March 2019 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: