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.


Anmelden zum Antworten