Skip to main content
deleted 1 character in body
Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72
std::string longest_valid_word(std::ifstream& is) {
    std::string buffer;
    std::string longest_word;
    while (std::getline(is, buffer)) {
        if (buffer.size() > longest_word.size() && !is_valid_word(buffer)) {
            longest_word = buffer;
        }
    }

    return longest_word;
}
std::string longest_valid_word(std::ifstream& is) {
    std::string buffer;
    std::string longest_word;
    while (std::getline(is, buffer)) {
        if (buffer.size() > longest_word.size() && !is_valid_word(buffer)) {
            longest_word = buffer;
        }
    }

    return longest_word;
}
std::string longest_valid_word(std::ifstream& is) {
    std::string buffer;
    std::string longest_word;
    while (std::getline(is, buffer)) {
        if (buffer.size() > longest_word.size() && is_valid_word(buffer)) {
            longest_word = buffer;
        }
    }

    return longest_word;
}
deleted 139 characters in body
Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72
template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
    std::string longest_word;
    while (first != last) {
        auto word = *first;
        if (word.sizefirst->size() > longest_word.size() && is_valid_word(word*first)) {
            longest_word = std::move(word);*first;
        }
        ++first;
    }

    return longest_word;
}
#include <string_view>
#include <utility>
#include <string>
#include <fstream>
#include <iterator>
#include <chrono>
#include <atomic>
#include <iostream>

bool is_valid_word(std::string_view word) {
    for (char letter: word) {
        switch (letter) {
            case 'g':
            case 'k':
            case 'm':
            case 'q':
            case 'v':
            case 'w':
            case 'x':
            case 'z':
                return false;
            default:
                ; //silence warnings
        }
    }

    return true;
}

template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
    std::string longest_word;
    while (first != last) {
        if (first->size() > longest_word.size() && is_valid_word(*first)) {
            longest_word = std::move(*first);*first;
        }
        ++first;
    }

    return longest_word;
}

int main() {
    std::ifstream file("words.txt");
    auto first = std::istream_iterator<std::string>(file);
    auto last = std::istream_iterator<std::string>();

    using namespace std::chrono;
    auto start_time = system_clock::now();
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto found_word = longest_valid_word(firststd::istream_iterator<std::string>(file), last{});
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto end_time = system_clock::now();

    auto duration = duration_cast<milliseconds>(end_time - start_time);

    std::cout << "[" << duration.count() << "ms] "
              << found_word << std::endl;
}
std::string longest_valid_word(std::ifstream& is) {
    std::string buffer;
    std::string longest_word;
    while (std::getline(is, buffer)) {
        if (buffer.size() > longest_word.size() && !is_valid_word(buffer)) {
            longest_word = std::move(buffer);buffer;
        }
    }

    return longest_word;
}
template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
    std::string longest_word;
    while (first != last) {
        auto word = *first;
        if (word.size() > longest_word.size() && is_valid_word(word)) {
            longest_word = std::move(word);
        }
        ++first;
    }

    return longest_word;
}
#include <string_view>
#include <utility>
#include <string>
#include <fstream>
#include <iterator>
#include <chrono>
#include <atomic>
#include <iostream>

bool is_valid_word(std::string_view word) {
    for (char letter: word) {
        switch (letter) {
            case 'g':
            case 'k':
            case 'm':
            case 'q':
            case 'v':
            case 'w':
            case 'x':
            case 'z':
                return false;
            default:
                ; //silence warnings
        }
    }

    return true;
}

template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
    std::string longest_word;
    while (first != last) {
        if (first->size() > longest_word.size() && is_valid_word(*first)) {
            longest_word = std::move(*first);
        }
        ++first;
    }

    return longest_word;
}

int main() {
    std::ifstream file("words.txt");
    auto first = std::istream_iterator<std::string>(file);
    auto last = std::istream_iterator<std::string>();

    using namespace std::chrono;
    auto start_time = system_clock::now();
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto found_word = longest_valid_word(first, last);
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto end_time = system_clock::now();

    auto duration = duration_cast<milliseconds>(end_time - start_time);

    std::cout << "[" << duration.count() << "ms] "
              << found_word << std::endl;
}
std::string longest_valid_word(std::ifstream& is) {
    std::string buffer;
    std::string longest_word;
    while (std::getline(is, buffer)) {
        if (buffer.size() > longest_word.size() && !is_valid_word(buffer)) {
            longest_word = std::move(buffer);
        }
    }

    return longest_word;
}
template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
    std::string longest_word;
    while (first != last) {
        if (first->size() > longest_word.size() && is_valid_word(*first)) {
            longest_word = *first;
        }
        ++first;
    }

    return longest_word;
}
#include <string_view>
#include <utility>
#include <string>
#include <fstream>
#include <iterator>
#include <chrono>
#include <atomic>
#include <iostream>

bool is_valid_word(std::string_view word) {
    for (char letter: word) {
        switch (letter) {
            case 'g':
            case 'k':
            case 'm':
            case 'q':
            case 'v':
            case 'w':
            case 'x':
            case 'z':
                return false;
            default:
                ; //silence warnings
        }
    }

    return true;
}

template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
    std::string longest_word;
    while (first != last) {
        if (first->size() > longest_word.size() && is_valid_word(*first)) {
            longest_word = *first;
        }
        ++first;
    }

    return longest_word;
}

int main() {
    std::ifstream file("words.txt");

    using namespace std::chrono;
    auto start_time = system_clock::now();
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto found_word = longest_valid_word(std::istream_iterator<std::string>(file), {});
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto end_time = system_clock::now();

    auto duration = duration_cast<milliseconds>(end_time - start_time);

    std::cout << "[" << duration.count() << "ms] "
              << found_word << std::endl;
}
std::string longest_valid_word(std::ifstream& is) {
    std::string buffer;
    std::string longest_word;
    while (std::getline(is, buffer)) {
        if (buffer.size() > longest_word.size() && !is_valid_word(buffer)) {
            longest_word = buffer;
        }
    }

    return longest_word;
}
added 890 characters in body
Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72
#include <string_view>
#include <utility>
#include <string>
#include <fstream>
#include <iterator>
#include <chrono>
#include <atomic>
#include <iostream>

bool is_valid_word(std::string_view word) {
    for (char letter: word) {
        switch (letter) {
            case 'g':
            case 'k':
            case 'm':
            case 'q':
            case 'v':
            case 'w':
            case 'x':
            case 'z':
                return false;
            default:
                ; //silence warnings
        }
    }

    return true;
}

template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
    std::string longest_word;
    while (first != last) {
        auto word = *first;
        if (word.sizefirst->size() > longest_word.size() && is_valid_word(word*first)) {
            longest_word = std::move(word*first);
        }
        ++first;
    }

    return longest_word;
}

#include <fstream>
#include <iterator>
#include <chrono>
#include <atomic>
#include <iostream>

int main() {
    std::ios_base::sync_with_stdio(false);
    std::ifstream file("words.txt");
    auto first = std::istream_iterator<std::string>(file);
    auto last = std::istream_iterator<std::string>();

    using namespace std::chrono;
    auto start_time = system_clock::now();
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto found_word = longest_valid_word(first, last);
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto end_time = system_clock::now();

    std::coutauto <<duration "longest= wordduration_cast<milliseconds>(end_time is- "start_time);

 << found_word  std::cout << ""[" and<< itduration.count() took<< "ms] "
              << duration_cast<microseconds>(end_time - start_time).count()found_word << " microseconds\n";std::endl;
}

Well,Well, I got around 90-100 milliseconds on my machine. I've got no idea why it runs so slowly, but I've exhausted my sane ideas. The other one would be to do some manual parsing of the file, which is much harder.

Of course it didn't go as I got around 90-100 milliseconds on my machineexpected :) this is what happens when optimizations are done in a rush. I've got no ideaLet me break down why it runs so slowlythe code above is slower than what Toby and Edward (my speculations from results, but I've exhausted my sane ideas. The other one would be to do some manual parsing of course):

  • std::getline is faster than using std::istream_iterator<std::string>

  • using jump table or just using array of bad letters make no difference whatsoever on my timings

Different version of alternative approach (uses std::getline)

std::string longest_valid_word(std::ifstream& is) {
    std::string buffer;
    std::string longest_word;
    while (std::getline(is, buffer)) {
        if (buffer.size() > longest_word.size() && !is_valid_word(buffer)) {
            longest_word = std::move(buffer);
        }
    }

    return longest_word;
}

Just paste the function into the code and call it with the file stream, which is much harderinstead of calling the one with iterators.

#include <string_view>
#include <utility>
#include <string>

bool is_valid_word(std::string_view word) {
    for (char letter: word) {
        switch (letter) {
            case 'g':
            case 'k':
            case 'm':
            case 'q':
            case 'v':
            case 'w':
            case 'x':
            case 'z':
                return false;
            default:
                ; //silence warnings
        }
    }

    return true;
}

template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
    std::string longest_word;
    while (first != last) {
        auto word = *first;
        if (word.size() > longest_word.size() && is_valid_word(word)) {
            longest_word = std::move(word);
        }
        ++first;
    }

    return longest_word;
}

#include <fstream>
#include <iterator>
#include <chrono>
#include <atomic>
#include <iostream>

int main() {
    std::ios_base::sync_with_stdio(false);
    std::ifstream file("words.txt");
    auto first = std::istream_iterator<std::string>(file);
    auto last = std::istream_iterator<std::string>();

    using namespace std::chrono;
    auto start_time = system_clock::now();
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto found_word = longest_valid_word(first, last);
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto end_time = system_clock::now();

    std::cout << "longest word is " << found_word << " and it took "
              << duration_cast<microseconds>(end_time - start_time).count() << " microseconds\n";
}

Well, I got around 90-100 milliseconds on my machine. I've got no idea why it runs so slowly, but I've exhausted my sane ideas. The other one would be to do some manual parsing of the file, which is much harder.

#include <string_view>
#include <utility>
#include <string>
#include <fstream>
#include <iterator>
#include <chrono>
#include <atomic>
#include <iostream>

bool is_valid_word(std::string_view word) {
    for (char letter: word) {
        switch (letter) {
            case 'g':
            case 'k':
            case 'm':
            case 'q':
            case 'v':
            case 'w':
            case 'x':
            case 'z':
                return false;
            default:
                ; //silence warnings
        }
    }

    return true;
}

template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
    std::string longest_word;
    while (first != last) {
        if (first->size() > longest_word.size() && is_valid_word(*first)) {
            longest_word = std::move(*first);
        }
        ++first;
    }

    return longest_word;
}

int main() {
    std::ifstream file("words.txt");
    auto first = std::istream_iterator<std::string>(file);
    auto last = std::istream_iterator<std::string>();

    using namespace std::chrono;
    auto start_time = system_clock::now();
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto found_word = longest_valid_word(first, last);
    //std::atomic_thread_fence(std::memory_order_seq_cst);
    auto end_time = system_clock::now();

    auto duration = duration_cast<milliseconds>(end_time - start_time);

    std::cout << "[" << duration.count() << "ms] "
              << found_word << std::endl;
}

Well, I got around 90-100 milliseconds on my machine. I've got no idea why it runs so slowly, but I've exhausted my sane ideas. The other one would be to do some manual parsing of the file, which is much harder.

Of course it didn't go as I expected :) this is what happens when optimizations are done in a rush. Let me break down why the code above is slower than what Toby and Edward (my speculations from results, of course):

  • std::getline is faster than using std::istream_iterator<std::string>

  • using jump table or just using array of bad letters make no difference whatsoever on my timings

Different version of alternative approach (uses std::getline)

std::string longest_valid_word(std::ifstream& is) {
    std::string buffer;
    std::string longest_word;
    while (std::getline(is, buffer)) {
        if (buffer.size() > longest_word.size() && !is_valid_word(buffer)) {
            longest_word = std::move(buffer);
        }
    }

    return longest_word;
}

Just paste the function into the code and call it with the file stream, instead of calling the one with iterators.

deleted 2 characters in body
Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72
Loading
deleted 59 characters in body
Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72
Loading
Source Link
Incomputable
  • 9.6k
  • 3
  • 33
  • 72
Loading