Brainf*** Interpreter (Benchmark)
-
Hallo.
Ich habe grade aus langeweile so nen Brainf*** Interpreter gecodet (in C++).
Jetzt will ich gucken, ob er auch schnell geht.
Gibts da nicht so ne art Benchmark für so was?
-
Kannst ihn ja mit meinem vergleichen...

// Brainfuck.cpp: STL based brainfuck interpreter #include <iostream> #include <fstream> #include <string> #include <vector> using namespace std; // Main function int main(int argc, char* argv[]) { // Do we have enough arguments? if(argc == 2) { // Try to open file ifstream fileIn(argv[1]); if(fileIn) { // Read in the file string strCode; for(string strRead; getline(fileIn, strRead);) strCode += strRead; // Set up the the code pointer string::iterator itCode = strCode.begin(); // Brainfuck requires an array of 30,000 bytes, initially all set to zero vector<char> arrData(30000); fill(arrData.begin(), arrData.end(), 0); // The pointer is initialized to point to the beginning of this array vector<char>::iterator itData = arrData.begin(); // Interpret the code while(itCode != strCode.end()) { bool bIncrement = true; switch(*itCode) { case '>': // Increment the pointer ++itData; break; case '<': // Decrement the pointer --itData; break; case '+': // Increment the byte at the pointer ++*itData; break; case '-': // Decrement the byte at the pointer --*itData; break; case '.': // Output the byte at the pointer cout << *itData; break; case ',': // Input a byte and store it in the byte at the pointer cin >> *itData; break; case '[': // Jump past the matching ] if the byte at the pointer is zero if(*itData == 0) { int x = 1; while(true) { if(*++itCode == '[') ++x; else if(*itCode == ']') { if(--x == 0) break; } } } break; case ']': // Jump to the matching [ if(*itData != 0) { int x = 1; while(true) { if(*--itCode == ']') ++x; else if(*itCode == '[') { if(--x == 0) break; } } bIncrement = false; } break; default: // unknown command is ignored break; } // Increment code pointer if(bIncrement) ++itCode; } } } }
-
Kannst ihn auch mal mit meinem vergleichen:
/*************************************************************************** * Copyright (C) 2003 by Tino Wagner * * ich@tinowagner.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include <iostream> #include <fstream> #include <vector> #include <string> template <typename T> class Stack { public: Stack() { m_head = new Item; m_foot = new Item; m_head->next = m_foot; m_foot->next = m_foot; } void push(T item) { Item *t = new Item; t->item = item; t->next = m_head->next; m_head->next = t; } void pop() { Item *t = m_head->next; m_head->next = t->next; delete t; } T top() { return m_head->next->item; } private: struct Item { Item *next; T item; } *m_head, *m_foot; }; template <typename code = std::ifstream, typename in = std::istream, typename out = std::ostream> class BfParser { public: BfParser(code& codestream, int memsize, in& input = std::cin, out& output = std::cout) : m_input(input), m_output(output), m_memory(memsize) { while(!codestream.eof()) m_code.push_back(codestream.get()); m_mempointer = m_memory.begin(); } ~BfParser() { } void parse() { int mcnt; for(charvector::iterator i = m_code.begin(); i != m_code.end(); ++i) { switch(*i) { case add: ++*m_mempointer; break; case sub: --*m_mempointer; break; case back: if(m_mempointer != m_memory.begin()) --m_mempointer; break; case forward: if(m_mempointer != m_memory.end()) ++m_mempointer; break; case loop_begin: m_loopstarts.push(i-1); if(*m_mempointer == 0) { charvector::iterator closing_pos = i; int cnt = 0; for(;;) { ++closing_pos; if(*closing_pos == loop_begin) ++cnt; if(*closing_pos == loop_end) { if(cnt>0) --cnt; else break; } } i = closing_pos; m_loopstarts.pop(); } break; case loop_end: i = m_loopstarts.top(); m_loopstarts.pop(); break; case output: m_output.put(*m_mempointer); break; case input: *m_mempointer = m_input.get(); break; } } } private: in& m_input; out& m_output; typedef std::vector<char> charvector; charvector m_code; Stack<charvector::iterator> m_loopstarts; charvector m_memory; charvector::iterator m_mempointer; enum instructions { add = '+', sub = '-', back = '<', forward = '>', loop_begin = '[', loop_end = ']', output = '.', input = ',' }; }; int main(int argc, char *argv[]) { if(argc>1) { std::ifstream in(argv[1]); if(!in) return 1; BfParser<> parser(in, 30000); parser.parse(); } std::cout << std::endl; }(Den Stack hatte ich aus Performancegründen eingebaut, bringt aber nicht viel.)
Aber ich sag dir jetzt schon, dass einer schneller ist. Nämlich der hier: http://sourceforge.net/projects/bfint .
Und zum Benchmarken bietet sich ein Mandelbrot an: http://esoteric.sange.fi/brainfuck/utils/mandelbrot/ .
-
Danke.
Ich werd mich morgen mal drüberstürzen.