diff --git a/CMakeLists.txt b/CMakeLists.txt
index f3e438dde755d32838527340444cc7ea8950bbe6..70cd1703807158f5af893bd044864b256fea61a6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,6 +22,7 @@ set(SRC_FILES
 	strops.cpp
 	translators.cpp
 	randomgen.cpp
+	compile.cpp
 )
 
 set(API_HEADERS_CPP_DIR eisgenerator/)
diff --git a/cap.cpp b/cap.cpp
index 191fad6a02b0996f1af909d0ba86925ebe2c939d..eb8078185e6a4054bee66742cacf111cf7bfa055 100644
--- a/cap.cpp
+++ b/cap.cpp
@@ -45,3 +45,13 @@ size_t Cap::paramCount()
 {
 	return 1;
 }
+
+std::string Cap::getCode(std::vector<std::string>& parameters)
+{
+	std::string firstParameter = getUniqueName() + "_0";
+	parameters.push_back(firstParameter);
+	std::string real = "0";
+	std::string imag = "0.0-(1.0/(" + firstParameter + "*omega))";
+	std::string out = "std::complex<fvalue>(" + real + ", " + imag + ")";
+	return out;
+}
diff --git a/compile.cpp b/compile.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..00b86298c610a1bfce02b22effc2b9950834eb11
--- /dev/null
+++ b/compile.cpp
@@ -0,0 +1,149 @@
+#include "compile.h"
+
+#include <filesystem>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdexcept>
+#include <sys/wait.h>
+#include <dlfcn.h>
+
+#include "log.h"
+
+using namespace eis;
+
+static constexpr int PIPE_READ = 0;
+static constexpr int PIPE_WRITE = 1;
+
+int eis::compile_code(const std::string& code, const std::string& outputName)
+{
+	int childStdinPipe[2];
+	int childStdoutPipe[2];
+
+	int ret = pipe(childStdinPipe);
+	if(ret < 0)
+		throw std::runtime_error("Not enough pipe to create child");
+	ret = pipe(childStdoutPipe);
+	if(ret < 0)
+		throw std::runtime_error("Not enough pipe to create child");
+
+	int childPid = fork();
+
+	if(childPid < 0)
+		throw std::runtime_error("Unable to create child");
+
+	if(childPid == 0)
+	{
+		eis::Log(eis::Log::DEBUG)<<"Compile starting";
+
+		if (dup2(childStdinPipe[PIPE_READ], STDIN_FILENO) == -1)
+			exit(errno);
+		if (dup2(childStdoutPipe[PIPE_WRITE], STDOUT_FILENO) == -1)
+			exit(errno);
+		if (dup2(childStdoutPipe[PIPE_WRITE], STDERR_FILENO) == -1)
+			exit(errno);
+
+		close(childStdinPipe[PIPE_WRITE]);
+		close(childStdinPipe[PIPE_READ]);
+		close(childStdoutPipe[PIPE_WRITE]);
+		close(childStdoutPipe[PIPE_READ]);
+
+		ret = execlp("g++", "gcc", "--shared", "-O2", "-ffast-math", "-ftree-vectorize", "-mavx", "-x", "c++", "-o", outputName.c_str(), "-", NULL);
+
+		exit(ret);
+	}
+	else
+	{
+		eis::Log(eis::Log::DEBUG)<<"Sending code to child";
+
+		close(childStdinPipe[PIPE_READ]);
+		close(childStdoutPipe[PIPE_WRITE]);
+
+		ret = write(childStdinPipe[PIPE_WRITE], code.c_str(), code.size());
+		if(ret < 0)
+			throw std::runtime_error("Could not pass code to compiler");
+		close(childStdinPipe[PIPE_WRITE]);
+
+		char ch;
+		while (read(childStdoutPipe[PIPE_READ], &ch, 1) == 1)
+			eis::Log(eis::Log::DEBUG, false)<<ch;
+
+		close(childStdoutPipe[PIPE_READ]);
+
+		eis::Log(eis::Log::DEBUG)<<"Wating for child to exit";
+
+		int exitCode;
+		waitpid(childPid, &exitCode, 0);
+		if(exitCode != 0)
+			eis::Log(eis::Log::ERROR)<<"Failed to compile "<<exitCode;
+		eis::Log(eis::Log::DEBUG)<<"Chiled exited";
+		return exitCode;
+	}
+	return -1;
+}
+
+std::string eis::getTempdir()
+{
+	char* tmpEnv = getenv("TMP");
+	char* tempEnv = getenv("TEMP");
+	char* tempDirEnv = getenv("TEMPDIR");
+
+	std::filesystem::path path;
+	if(tmpEnv && std::string(tmpEnv).length() > 1)
+		path = tmpEnv;
+	else if(tempEnv && std::string(tempEnv).length() > 1)
+		path = tempEnv;
+	else if(tempDirEnv && std::string(tempDirEnv).length() > 1)
+		path = tempDirEnv;
+	else
+		path = "/tmp";
+	path = path/"eis_models";
+
+	if(!std::filesystem::is_directory(path))
+	{
+		if(!std::filesystem::create_directory(path))
+			throw std::runtime_error(path.string() +
+				"is not a directory and a directory can not be created at this locaion");
+	}
+
+	return path;
+}
+
+
+CompCache* CompCache::getInstance()
+{
+	if(!instance)
+		instance = new CompCache();
+	return instance;
+}
+
+bool CompCache::addObject(size_t uuid, const CompiledObject& object)
+{
+	CompiledObject* foundobject = getObject(uuid);
+	if(foundobject)
+		return false;
+
+	objects.insert({uuid, new CompiledObject(object)});
+	return true;
+}
+
+CompiledObject* CompCache::getObject(size_t uuid)
+{
+	auto search = objects.find(uuid);
+	if(search == objects.end())
+		return nullptr;
+	else
+		return search->second;
+}
+
+void CompCache::dropAllObjects()
+{
+	for(std::pair<size_t, CompiledObject*> object : objects)
+	{
+		dlclose(object.second->objectCode);
+		delete object.second;
+	}
+
+	objects.clear();
+}
diff --git a/compile.h b/compile.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce0ababf8d84d189613ae5021faa17b6c0c08682
--- /dev/null
+++ b/compile.h
@@ -0,0 +1,41 @@
+#include <string>
+#include <vector>
+#include <map>
+#include <complex>
+
+#include "eistype.h"
+
+namespace eis
+{
+
+int compile_code(const std::string& code, const std::string& outputName);
+
+std::string getTempdir();
+
+struct CompiledObject
+{
+	void* objectCode;
+	std::vector<std::complex<fvalue>>(*symbol)(const std::vector<fvalue>&, const std::vector<fvalue>&);
+};
+
+class CompCache
+{
+public:
+
+private:
+
+	inline static CompCache* instance = nullptr;
+	std::map<size_t, CompiledObject*> objects;
+	CompCache() {};
+
+public:
+
+	static CompCache* getInstance();
+	CompCache(const CompCache&) = delete;
+	CompCache& operator=(const CompCache&) = delete;
+	bool addObject(size_t uuid, const CompiledObject& object);
+	CompiledObject* getObject(size_t uuid);
+	void dropAllObjects();
+};
+
+}
diff --git a/componant.cpp b/componant.cpp
index 36bf5c810e79650e476f7b7b42ba83af46dd1e73..d016bbd61143749eeb4b749fa1b1409693456299 100644
--- a/componant.cpp
+++ b/componant.cpp
@@ -56,13 +56,13 @@ std::string Componant::getUniqueName()
 {
 	if(uniqueName.empty())
 	{
-		uniqueName.assign(getComponantChar(), 5);
-		for(size_t i = 1; i < uniqueName.size(); ++i)
+		uniqueName.push_back(getComponantChar());
+		for(size_t i = 0; i < 3; ++i)
 		{
 			char ch = static_cast<char>(rd::rand(122-65)+65);
 			if(ch > 90 && ch < 97)
 				ch = ch + 6;
-			uniqueName[i] = ch;
+			uniqueName.push_back(ch);
 		}
 	}
 	return uniqueName;
@@ -95,3 +95,14 @@ Componant* Componant::copy(Componant* componant)
 	}
 	return nullptr;
 }
+
+bool Componant::compileable()
+{
+	std::vector<std::string> parameters;
+	return !getCode(parameters).empty();
+}
+
+std::string Componant::getCode(std::vector<std::string>& parameters)
+{
+	return std::string();
+}
diff --git a/constantphase.cpp b/constantphase.cpp
index 12aba56b1f5d4a1ebb21c9d94420f11dc4f09ddc..4a9f6eca12b6412262f60e23c5dfc192e9a5c3a9 100644
--- a/constantphase.cpp
+++ b/constantphase.cpp
@@ -56,8 +56,9 @@ void Cpe::setDefaultParam(size_t count, bool defaultToRange)
 std::complex<fvalue> Cpe::execute(fvalue omega)
 {
 	assert(ranges.size() == paramCount());
-	return std::complex<fvalue>((1.0/(ranges[0][ranges[0].step]*pow(omega, ranges[1][ranges[1].step])))*cos((M_PI/2)*ranges[1][ranges[1].step]),
-	                           0-(1.0/(ranges[0][ranges[0].step]*pow(omega, ranges[1][ranges[1].step])))*sin((M_PI/2)*ranges[1][ranges[1].step]));
+	fvalue real = (1.0/(ranges[0][ranges[0].step]*std::pow(omega, ranges[1][ranges[1].step])))*std::cos((M_PI/2)*ranges[1][ranges[1].step]);
+	fvalue imag = 0-(1.0/(ranges[0][ranges[0].step]*std::pow(omega, ranges[1][ranges[1].step])))*std::sin((M_PI/2)*ranges[1][ranges[1].step]);
+	return std::complex<fvalue>(real, imag);
 }
 
 size_t Cpe::paramCount()
@@ -69,3 +70,15 @@ char Cpe::getComponantChar() const
 {
 	return Cpe::staticGetComponantChar();
 }
+
+std::string Cpe::getCode(std::vector<std::string>& parameters)
+{
+	std::string firstParameter = getUniqueName() + "_0";
+	std::string secondParameter = getUniqueName() + "_1";
+	parameters.push_back(firstParameter);
+	parameters.push_back(secondParameter);
+	std::string real = "(1.0/(" + firstParameter + "*std::pow(omega," + secondParameter + ")))*std::cos((M_PI/2)*" + secondParameter + ")";
+	std::string imag = "0-(1.0/(" + firstParameter + "*std::pow(omega," + secondParameter + ")))*std::sin((M_PI/2)*" + secondParameter + ")";
+	std::string out = "std::complex<fvalue>(" + real +", " + imag + ")";
+	return out;
+}
diff --git a/eisgenerator/cap.h b/eisgenerator/cap.h
index 54ef8a473751e610aaacf3f9d8094288e4f0207c..40a1080ae687cd8e05c2de7662b244eb52390115 100644
--- a/eisgenerator/cap.h
+++ b/eisgenerator/cap.h
@@ -17,6 +17,7 @@ public:
 	virtual char getComponantChar() const override;
 	static constexpr char staticGetComponantChar(){return 'c';}
 	virtual std::string componantName() const override {return "Capacitor";}
+	virtual std::string getCode(std::vector<std::string>& parameters) override;
 	virtual ~Cap() = default;
 };
 
diff --git a/eisgenerator/componant.h b/eisgenerator/componant.h
index a4c101cb8395b459a2f26b5f88d059147caa139e..6bc1b1a94ce498004435f1f23f70b743c745e332 100644
--- a/eisgenerator/componant.h
+++ b/eisgenerator/componant.h
@@ -31,6 +31,8 @@ class Componant
 		virtual char getComponantChar() const = 0;
 		virtual std::string getComponantString(bool currentValue = true) const;
 		virtual std::string componantName() const = 0;
+		virtual std::string getCode(std::vector<std::string>& parameters);
+		virtual bool compileable();
 
 		std::string getUniqueName();
 
diff --git a/eisgenerator/constantphase.h b/eisgenerator/constantphase.h
index 7a2fb27872c82500db0e18014edd631de369e7ad..8bb0c58d0dae330285acd52aa7858a3362283dab 100644
--- a/eisgenerator/constantphase.h
+++ b/eisgenerator/constantphase.h
@@ -21,7 +21,7 @@ public:
 	static constexpr char staticGetComponantChar(){return 'p';}
 	virtual std::string componantName() const override {return "ConstantPhase";}
 	virtual ~Cpe() = default;
-
+	virtual std::string getCode(std::vector<std::string>& parameters) override;
 };
 
 }
diff --git a/eisgenerator/inductor.h b/eisgenerator/inductor.h
index 61a5ab24b6baf549086cc7c8491a739c69c5d30b..a410eccb6c25687d6f926b62002fd3499c3d8eac 100644
--- a/eisgenerator/inductor.h
+++ b/eisgenerator/inductor.h
@@ -17,6 +17,7 @@ public:
 	virtual char getComponantChar() const override;
 	static constexpr char staticGetComponantChar(){return 'l';}
 	virtual std::string componantName() const override {return "Inductor";}
+	virtual std::string getCode(std::vector<std::string>& parameters) override;
 	virtual ~Inductor() = default;
 };
 
diff --git a/eisgenerator/model.h b/eisgenerator/model.h
index 8db355a641c935455c0ba6c10730c2a346628d9a..1dbac364a6d692d8c27754fb87b4d76cb65dafc6 100644
--- a/eisgenerator/model.h
+++ b/eisgenerator/model.h
@@ -5,12 +5,15 @@
 #include <string>
 #include <vector>
 #include <functional>
+
 #include "eistype.h"
 #include "componant.h"
 
 namespace eis
 {
 
+struct CompiledObject;
+
 class Model
 {
 private:
@@ -19,6 +22,7 @@ private:
 	std::string getParamStr(const std::string& str, size_t index);
 	static size_t paramSkipIndex(const std::string& str, size_t index);
 	static void addComponantToFlat(Componant* componant, std::vector<Componant*>* flatComponants);
+	std::vector<fvalue> getFlatParameters();
 
 	static void sweepThreadFn(std::vector<std::vector<DataPoint>>* data, Model* model, size_t start, size_t stop, const Range& omega);
 
@@ -29,6 +33,8 @@ private:
 	std::vector<Componant*> _bracketComponants;
 	std::string _modelStr;
 	std::vector<Componant*> _flatComponants;
+	std::string _modelUuid;
+	CompiledObject* _compiledModel = nullptr;
 
 public:
 	Model(const std::string& str, size_t paramSweepCount = 100, bool defaultToRange = true);
@@ -42,12 +48,15 @@ public:
 	std::string getModelStr() const;
 	std::string getModelStrWithParam(size_t index);
 	std::string getModelStrWithParam() const;
+	size_t getUuid();
 	std::vector<Componant*> getFlatComponants(Componant *model = nullptr);
 	size_t getParameterCount();
+	bool compile();
 	bool isReady();
 	void resolveSteps(int64_t index);
 	size_t getRequiredStepsForSweeps();
 	bool isParamSweep();
+	std::string getCode();
 	std::vector<size_t> getRecommendedParamIndices(eis::Range omegaRange, double distance, bool threaded = false);
 };
 
diff --git a/eisgenerator/paralellseriel.h b/eisgenerator/paralellseriel.h
index cd77b3e6b20eae17bf0c38c21be1b312b51119a2..902bbe4874a214e7467271b4a5760c816242232a 100644
--- a/eisgenerator/paralellseriel.h
+++ b/eisgenerator/paralellseriel.h
@@ -20,6 +20,8 @@ public:
 	virtual std::string getComponantString(bool currentValue = true) const override;
 	static constexpr char staticGetComponantChar(){return 'd';}
 	virtual std::string componantName() const override {return "Parallel";}
+	virtual bool compileable() override;
+	virtual std::string getCode(std::vector<std::string>& parameters) override;
 };
 
 class Serial: public Componant
@@ -36,6 +38,8 @@ public:
 	virtual std::string getComponantString(bool currentValue = true) const override;
 	static constexpr char staticGetComponantChar(){return 's';}
 	virtual std::string componantName() const override {return "Serial";}
+	virtual bool compileable() override;
+	virtual std::string getCode(std::vector<std::string>& parameters) override;
 };
 
 }
diff --git a/eisgenerator/resistor.h b/eisgenerator/resistor.h
index 6822313535aa38ad1f402675ca440e94f27ba31f..53501b1c2c451b76d41d0f7894525c596481b218 100644
--- a/eisgenerator/resistor.h
+++ b/eisgenerator/resistor.h
@@ -15,6 +15,7 @@ public:
 	virtual char getComponantChar() const override;
 	static constexpr char staticGetComponantChar(){return 'r';}
 	virtual std::string componantName() const override {return "Resistor";}
+	virtual std::string getCode(std::vector<std::string>& parameters) override;
 	virtual ~Resistor() = default;
 };
 
diff --git a/eisgenerator/warburg.h b/eisgenerator/warburg.h
index 706d9afcb3bd526fe2f034dbdf295eea12b953c5..4ace89f365abae96a59b3e796b59d82c311d6c24 100644
--- a/eisgenerator/warburg.h
+++ b/eisgenerator/warburg.h
@@ -17,6 +17,7 @@ public:
 	virtual char getComponantChar() const override;
 	static constexpr char staticGetComponantChar(){return 'w';}
 	virtual std::string componantName() const override {return "Warburg";}
+	virtual std::string getCode(std::vector<std::string>& parameters) override;
 	virtual ~Warburg() = default;
 };
 
diff --git a/inductor.cpp b/inductor.cpp
index 77c9714a4edde369b717a2ba67b121064e937ed4..32428a342e73de317e5a162191ae085bce0eeaec 100644
--- a/inductor.cpp
+++ b/inductor.cpp
@@ -45,3 +45,11 @@ char Inductor::getComponantChar() const
 {
 	return staticGetComponantChar();
 }
+
+std::string Inductor::getCode(std::vector<std::string>& parameters)
+{
+	parameters.push_back(getUniqueName() + "_0");
+	std::string N = parameters.back() + "*omega";
+	std::string out = "std::complex<fvalue>(0, " + N + ")";
+	return out;
+}
diff --git a/main.cpp b/main.cpp
index aa7a90e5e483debbd6cd5a89a67cfd0005d6537e..12e1387f1d255ea39ca23302be5e75d4f352e6d5 100644
--- a/main.cpp
+++ b/main.cpp
@@ -85,11 +85,18 @@ static void runParamSweep(const Config& config, eis::Model& model)
 	size_t count = model.getRequiredStepsForSweeps();
 	eis::Log(eis::Log::INFO)<<"Executeing "<<count<<" steps";
 
+	if(!config.noCompile)
+		model.compile();
+
 	auto start = std::chrono::high_resolution_clock::now();
 
 	std::vector<std::vector<eis::DataPoint>> allSweeps;
 	if(config.threaded)
+	{
+		eis::Log(eis::Log::INFO)<<"Calculateing sweeps in threads";
 		allSweeps = model.executeAllSweeps(config.omegaRange);
+		eis::Log(eis::Log::INFO)<<"Done";
+	}
 
 	for(size_t i = 0; i < count; ++i)
 	{
@@ -98,33 +105,37 @@ static void runParamSweep(const Config& config, eis::Model& model)
 			data = allSweeps[i];
 		else
 			data = model.executeSweep(config.omegaRange, i);
-		if(config.normalize)
-			eis::normalize(data);
-		if(config.reduce)
+
+		if(!config.noSave)
 		{
-			size_t initalDataSize = data.size();
-			data = eis::reduceRegion(data);
-			if(data.size() < initalDataSize/8)
+			if(config.normalize)
+				eis::normalize(data);
+			if(config.reduce)
 			{
-				eis::Log(eis::Log::INFO)<<"\nskipping output for step "<<i
-					<<" as data has no interesting region";
-				continue;
+				size_t initalDataSize = data.size();
+				data = eis::reduceRegion(data);
+				if(data.size() < initalDataSize/8)
+				{
+					eis::Log(eis::Log::INFO)<<"\nskipping output for step "<<i
+						<<" as data has no interesting region";
+					continue;
+				}
+				//data = eis::rescale(data, initalDataSize);
 			}
-			//data = eis::rescale(data, initalDataSize);
-		}
 
-		if(config.skipLinear && i > 0)
-		{
-			fvalue correlation = std::abs(pearsonCorrelation(data));
-			if(correlation > 0.5)
+			if(config.skipLinear && i > 0)
 			{
-				eis::Log(eis::Log::INFO)<<"skipping output for step "<<i
-					<<" as data is too linear: "<<correlation;
-				continue;
+				fvalue correlation = std::abs(pearsonCorrelation(data));
+				if(correlation > 0.5)
+				{
+					eis::Log(eis::Log::INFO)<<"skipping output for step "<<i
+						<<" as data is too linear: "<<correlation;
+					continue;
+				}
 			}
-		}
 
-		eis::saveToDisk(eis::EisSpectra(data, model.getModelStrWithParam(i), ""), std::string(PARA_SWEEP_OUTPUT_DIR)+std::string("/")+std::to_string(i)+".csv");
+			eis::saveToDisk(eis::EisSpectra(data, model.getModelStrWithParam(i), ""), std::string(PARA_SWEEP_OUTPUT_DIR)+std::string("/")+std::to_string(i)+".csv");
+		}
 		eis::Log(eis::Log::INFO, false)<<'.';
 	}
 	auto end = std::chrono::high_resolution_clock::now();
@@ -352,6 +363,10 @@ int main(int argc, char** argv)
 		{
 			outputRanges(config, model);
 		}
+		else if(config.mode == MODE_CODE)
+		{
+			std::cout<<model.getCode();
+		}
 		else
 		{
 			if(model.isParamSweep())
diff --git a/model.cpp b/model.cpp
index 5a8f420a71a862ad2d3d5f93d98bdb8a1957ddcc..fd9d1ccfd7471e2de3f0da53cc3b752956cf36d6 100644
--- a/model.cpp
+++ b/model.cpp
@@ -2,13 +2,18 @@
 #include <model.h>
 #include <iostream>
 #include <assert.h>
+#include <string>
 #include <vector>
 #include <array>
 #include <thread>
 #include <fstream>
 #include <algorithm>
 #include <execution>
+#include <dlfcn.h>
+#include <functional>
 
+#include "componant.h"
+#include "eistype.h"
 #include "strops.h"
 #include "cap.h"
 #include "resistor.h"
@@ -20,6 +25,8 @@
 #include "log.h"
 #include "normalize.h"
 #include "basicmath.h"
+#include "randomgen.h"
+#include "compile.h"
 
 using namespace eis;
 
@@ -196,6 +203,7 @@ Model& Model::operator=(const Model& in)
 	_bracketComponants.clear();
 	_flatComponants.clear();
 	_model = Componant::copy(in._model);
+	_compiledModel = in._compiledModel;
 	return *this;
 }
 
@@ -204,6 +212,21 @@ Model::~Model()
 	delete _model;
 }
 
+std::vector<fvalue> Model::getFlatParameters()
+{
+	std::vector<Componant*> flatComponants = getFlatComponants();
+
+	std::vector<fvalue> out;
+	out.reserve(getParameterCount());
+	for(Componant* componant : flatComponants)
+	{
+		const std::vector<Range> ranges = componant->getParamRanges();
+		for(const Range& range : ranges)
+			out.push_back(range.stepValue());
+	}
+	return out;
+}
+
 DataPoint Model::execute(fvalue omega, size_t index)
 {
 	if(_model)
@@ -307,12 +330,29 @@ std::vector<DataPoint> Model::executeSweep(const Range& omega, size_t index)
 {
 	std::vector<DataPoint> results;
 	results.reserve(omega.count);
-	for(size_t i = 0; i < omega.count; ++i)
+
+	if(_compiledModel)
+	{
+		resolveSteps(index);
+		std::vector<fvalue> parameters = getFlatParameters();
+		const std::vector<fvalue> omegas = omega.getRangeVector();
+		std::vector<std::complex<fvalue>> values = _compiledModel->symbol(parameters, omegas);
+		for(size_t i = 0; i < omegas.size(); ++i)
+		{
+			DataPoint dataPoint;
+			dataPoint.omega = omegas[i];
+			dataPoint.im = values[i];
+			results.push_back(dataPoint);
+		}
+	}
+	else
 	{
-		fvalue omegaStep = omega[i];
-		results.push_back(execute(omegaStep, index));
+		for(size_t i = 0; i < omega.count; ++i)
+		{
+			fvalue omegaStep = omega[i];
+			results.push_back(execute(omegaStep, index));
+		}
 	}
-
 	return results;
 }
 
@@ -373,22 +413,22 @@ void Model::resolveSteps(int64_t index)
 	std::vector<size_t> placeMagnitude;
 	placeMagnitude.reserve(flatRanges.size());
 
-	Log(Log::DEBUG)<<"Magnitudes:";
+	//Log(Log::DEBUG)<<"Magnitudes:";
 	for(size_t i = 0; i < flatRanges.size(); ++i)
 	{
 		size_t magnitude = 1;
 		for(int64_t j = static_cast<int64_t>(i)-1; j >= 0; --j)
 			magnitude = magnitude*flatRanges[j]->count;
 		placeMagnitude.push_back(magnitude);
-		Log(Log::DEBUG)<<placeMagnitude.back();
+		//Log(Log::DEBUG)<<placeMagnitude.back();
 	}
 
-	Log(Log::DEBUG)<<"Steps for index "<<index<<" ranges "<<flatRanges.size()<<" Ranges:";
+	//Log(Log::DEBUG)<<"Steps for index "<<index<<" ranges "<<flatRanges.size()<<" Ranges:";
 	for(int64_t i = flatRanges.size()-1; i >= 0; --i)
 	{
 		flatRanges[i]->step = index/placeMagnitude[i];
 		index = index % placeMagnitude[i];
-		Log(Log::DEBUG)<<placeMagnitude[i]<<'('<<flatRanges[i]->step<<')'<<(i == 0 ? "" : " + ");
+		//Log(Log::DEBUG)<<placeMagnitude[i]<<'('<<flatRanges[i]->step<<')'<<(i == 0 ? "" : " + ");
 	}
 }
 
@@ -519,3 +559,85 @@ std::vector<size_t> Model::getRecommendedParamIndices(eis::Range omegaRange, dou
 	eis::Log(eis::Log::INFO, false)<<'\n';
 	return indices;
 }
+
+size_t Model::getUuid()
+{
+	return std::hash<std::string>{}(getModelStr());
+}
+
+bool Model::compile()
+{
+	if(!_model->compileable())
+	{
+		Log(Log::WARN)<<"This model could not be compiled, expect performance degredation";
+		return false;
+	}
+
+	CompCache* cache = CompCache::getInstance();
+
+	_compiledModel = cache->getObject(getUuid());
+	if(!_compiledModel)
+	{
+		std::filesystem::path tmp = getTempdir();
+		size_t uuid = getUuid();
+
+		std::filesystem::path path = tmp/(std::to_string(getUuid())+".so");
+		int ret = compile_code(getCode(), path);
+		if(ret != 0)
+		{
+			Log(Log::WARN)<<"Unable to compile model!! expect performance degredation";
+			return false;
+		}
+
+		CompiledObject object;
+		object.objectCode = dlopen(path.c_str(), RTLD_NOW);
+		if(!object.objectCode)
+			throw std::runtime_error("Unable to dlopen compiled model " + std::string(dlerror()));
+
+		std::string symbolName = "model_" + std::to_string(getUuid());
+		object.symbol =
+			reinterpret_cast<std::vector<std::complex<fvalue>>(*)(const std::vector<fvalue>&, const std::vector<fvalue>&)>
+				(dlsym(object.objectCode, symbolName.c_str()));
+
+		if(!object.symbol)
+			throw std::runtime_error(path.string() + " dosent have a symbol " + symbolName);
+
+		cache->addObject(uuid, object);
+		_compiledModel = cache->getObject(uuid);
+	}
+
+	return true;
+}
+
+std::string Model::getCode()
+{
+	if(!_model || !_model->compileable())
+		return "";
+
+	std::vector<std::string> parameters;
+	std::string formular = _model->getCode(parameters);
+
+	std::string out =
+	"#include <cmath>\n"
+	"#include <cassert>\n"
+	"#include <vector>\n"
+	"#include <complex>\n\n"
+	"typedef float fvalue;\n\n"
+	"extern \"C\"\n{\n\n"
+	"std::vector<std::complex<fvalue>> model_";
+	out.append(std::to_string(getUuid()));
+	out.append("(const std::vector<fvalue>& parameters, const std::vector<fvalue> omegas)\n{\n\tassert(parameters.size() == ");
+	out.append(std::to_string(parameters.size()));
+	out.append(");\n\n");
+	out.append("\tstd::vector<std::complex<fvalue>> out(omegas.size());\n");
+
+	for(size_t i = 0; i < parameters.size(); ++i)
+		out.append("\tfvalue " + parameters[i] + " = parameters[" + std::to_string(i) +  "];\n");
+
+	out.append("\tfor(size_t i = 0; i < omegas.size(); ++i)\n\t{\n");
+	out.append("\t\tconst fvalue& omega = omegas[i];\n");
+	out.append("\t\tout[i] = ");
+	out.append(formular);
+	out.append(";\n\t}\n\treturn out;\n}\n\n}\n");
+	return out;
+}
diff --git a/options.h b/options.h
index 9624fa7fecc34b96aff1ea22aa64c63ca2038c99..9689d7f341783bbc5139144fe70620e9216bbc07 100644
--- a/options.h
+++ b/options.h
@@ -26,11 +26,13 @@ static struct argp_option options[] =
   {"invert",        'i', 0,      0,  "inverts the imaginary axis"},
   {"noise",        'x', "[AMPLITUDE]",      0,  "add noise to output"},
   {"input-type",   't', "[STRING]",      0,  "set input string type, possible values: eis, boukamp, relaxis, madap"},
-  {"find-range",   'f', "[STRING]",      0,  "mode, possible values: export, find-range, export-ranges"},
+  {"mode", 	       'f', "[STRING]",      0,  "mode, possible values: export, code, find-range, export-ranges"},
   {"range-distance",   'd', "[DISTANCE]",      0,  "distance from a previous point where a range is considered \"new\""},
   {"parallel",   'p', 0,      0,  "run on multiple threads"},
   {"skip-linear",   'e', 0,      0,  "dont output param sweeps that create linear nyquist plots"},
   {"default-to-range",   'b', 0,      0,  "if a element has no paramters, default to assigning it a range instead of a single value"},
+  {"no-compile",   'z', 0,      0,  "dont compile the model into a shared object"},
+  {"no-save",   'y', 0,      0,  "dont save sweeps"},
   { 0 }
 };
 
@@ -49,6 +51,7 @@ enum
 	MODE_FIND_RANGE,
 	MODE_OUTPUT_RANGE_DATAPOINTS,
 	MODE_INVALID,
+	MODE_CODE
 };
 
 struct Config
@@ -65,6 +68,8 @@ struct Config
 	bool threaded = false;
 	bool skipLinear = false;
 	bool defaultToRange = false;
+	bool noCompile = false;
+	bool noSave = false;
 	double noise = 0;
 	double rangeDistance = 0.35;
 
@@ -93,6 +98,8 @@ static int parseMode(const std::string& str)
 		return MODE_FIND_RANGE;
 	else if(str == "export-ranges")
 		return MODE_OUTPUT_RANGE_DATAPOINTS;
+	else if(str == "code")
+		return MODE_CODE;
 	return MODE_INVALID;
 }
 
@@ -190,6 +197,12 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	case 'b':
 		config->defaultToRange = true;
 		break;
+	case 'y':
+		config->noSave = true;
+		break;
+	case 'z':
+		config->noCompile = true;
+		break;
 	default:
 		return ARGP_ERR_UNKNOWN;
 	}
diff --git a/paralellseriel.cpp b/paralellseriel.cpp
index c36893912ef211826496417da6ecb5b21b3031a8..e661372f14a30abb42337e6bcaeb747e1cd1c48d 100644
--- a/paralellseriel.cpp
+++ b/paralellseriel.cpp
@@ -1,4 +1,5 @@
 #include "paralellseriel.h"
+#include "componant.h"
 
 using namespace eis;
 
@@ -49,6 +50,30 @@ std::string Parallel::getComponantString(bool currentValue) const
 	return out;
 }
 
+bool Parallel::compileable()
+{
+	for(Componant* componant : componants)
+	{
+		if(!componant->compileable())
+			return false;
+	}
+	return true;
+}
+
+std::string Parallel::getCode(std::vector<std::string>& parameters)
+{
+	std::string out = "std::complex<fvalue>(1,0)/(";
+	for(Componant* componant : componants)
+	{
+		out += "std::complex<fvalue>(1,0)/(" + componant->getCode(parameters) + ") + ";
+	}
+	out.pop_back();
+	out.pop_back();
+	out.pop_back();
+	out.push_back(')');
+	return out;
+}
+
 Serial::Serial(std::vector<Componant*> componantsIn): componants(componantsIn)
 {
 }
@@ -98,3 +123,27 @@ std::string Serial::getComponantString(bool currentValue) const
 	out.back() = ')';
 	return out;
 }
+
+bool Serial::compileable()
+{
+	for(Componant* componant : componants)
+	{
+		if(!componant->compileable())
+			return false;
+	}
+	return true;
+}
+
+std::string Serial::getCode(std::vector<std::string>& parameters)
+{
+	std::string out = "(";
+	for(Componant* componant : componants)
+	{
+		out += "(" + componant->getCode(parameters) + ") + ";
+	}
+	out.pop_back();
+	out.pop_back();
+	out.pop_back();
+	out.push_back(')');
+	return out;
+}
diff --git a/resistor.cpp b/resistor.cpp
index 074eeb6a5ea61122bb9512895ef26e991f6b5dd1..406702b1f7b37fc2929a2ffcc564626dc088785f 100644
--- a/resistor.cpp
+++ b/resistor.cpp
@@ -46,3 +46,10 @@ char Resistor::getComponantChar() const
 {
 	return staticGetComponantChar();
 }
+
+std::string Resistor::getCode(std::vector<std::string>& parameters)
+{
+	parameters.push_back(getUniqueName() + "_0");
+	std::string out = "std::complex<fvalue>(" + parameters.back() + ", 0)";
+	return out;
+}
diff --git a/warburg.cpp b/warburg.cpp
index 7155d5885bbe504ff4f11a0c9669a18a40b84229..a6c314d12fd4c6573761eb0962a64d989fdc3663 100644
--- a/warburg.cpp
+++ b/warburg.cpp
@@ -46,3 +46,11 @@ char Warburg::getComponantChar() const
 {
 	return staticGetComponantChar();
 }
+
+std::string Warburg::getCode(std::vector<std::string>& parameters)
+{
+	parameters.push_back(getUniqueName() + "_0");
+	std::string N = parameters.back() + "/std::sqrt(omega)";
+	std::string out = "std::complex<fvalue>(" + N + ", 0-" + N + ")";
+	return out;
+}