Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

помогите произвести и оптимизировать вычисление в динамически создаваемом dll

63K
28 сентября 2010 года
sanyur
8 / / 28.09.2010
Здравствуйте. помогите повысить быстродействие кода:

static double computer(string expression, string x)

{

// компилятор кода C#

ICodeCompiler cs = (new CSharpCodeProvider().CreateCompiler());

// параметры компиляции: DLL в памяти

CompilerParameters cp = new CompilerParameters();

cp.ReferencedAssemblies.Add("system.dll");

cp.GenerateExecutable = false; // создать DLL

cp.GenerateInMemory = true; // создать в памяти



// текст программы на C#:

string code = string.Empty;

code += "using System;\r\n ";

code += "namespace CSEvaluator\r\n";

code += "{ public class Evaluate\r\n";

code += " { public double GetResult()\r\n{double x = " + x + ";\r\n";

code += " return "+ expression +";\r\n }";

code += " private double exp(double x){ return(Math.Exp(x)); }";

code += " private double log(double x){ return(Math.Log(x)); }";

code += " private double log(double x,double s){ return(Math.Log(x,s)); }";

code += " private double pow(double x, double y){ return(Math.Pow(x,y)); }";

code += " private double sin(double x){ return(Math.Sin(x)); }";

code += " private double cos(double x){ return(Math.Cos(x)); }";

code += " private double pi(){ return(Math.PI); }";

code += " }\r\n";

code += "}";

text += code;



// компиляция исходного кода и получение сборки

CompilerResults cr = cs.CompileAssemblyFromSource(cp, code);

if (cr.Errors != null && cr.Errors.Count > 0) // ? ошибки

{

for (int i = 0; i < cr.Errors.Count; i++)

text += "Col {0} - {1}" + cr.Errors.Column + cr.Errors.ErrorText;

return -6666;

}



try // создать объект и вызвать метод для вычисления выражения

{

object ob = cr.CompiledAssembly.CreateInstance("CSEvaluator.Evaluate");

return ((double)ob.GetType().InvokeMember("GetResult", BindingFlags.InvokeMethod, null, ob, new object[] { }));

}

catch (Exception ex) { text += ex.Message; return (0); }

}

Необходимо произвести вычисления минимизации функции. так что данная функция вызывается много раз(например, при методе дихотомии 10 итераций, вызывается 20 раз), а вычисляется минимум функции за 12 секунд. можно ли сократить?

подскажите какая часть кода более трудоемкая.

можно ли создать dll глобально а потом вычислять getresult с параметром string x, передаваемой из texbox и намного ли быстрей будет в таком случае?
2.1K
29 сентября 2010 года
Norgat
452 / / 12.08.2009
оформи код тегами CODE.

на вскидку:

 
Код:
string code = string.Empty;
code += "using System;\r\n ";


от этого могут быть проблемы производительности, т.к. каждый раз при изменении объекта типа string происходит создание нового объекта типа string - результата операции, ссылка на который и заносится в code(а тут все радости создания новых объектов - включая как копирование объектов в памяти, так и вызов GC).

используй System.Text.StringBuilder вместо srting.
5
29 сентября 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: sanyur

Необходимо произвести вычисления минимизации функции. так что данная функция вызывается много раз(например, при методе дихотомии 10 итераций, вызывается 20 раз), а вычисляется минимум функции за 12 секунд. можно ли сократить?

И что, 20 раз происходит компиляция (вызов csc.exe)?
Покажите в каком контексте вы используете продемонстрированный код.

Цитата: Norgat
оформи код тегами CODE.


+1

Цитата: Norgat
используй System.Text.StringBuilder вместо srting.

В данном случае это ничего не даст вообще.

63K
29 сентября 2010 года
sanyur
8 / / 28.09.2010
Код:
static double computer(string expression, string x)
        {
            // компилятор кода C#
            ICodeCompiler cs = (new CSharpCodeProvider().CreateCompiler());
            // параметры компиляции: DLL в памяти
            CompilerParameters cp = new CompilerParameters();
            cp.ReferencedAssemblies.Add("system.dll");
            cp.GenerateExecutable = false; // создать DLL
            cp.GenerateInMemory = true;  // создать в памяти

            // текст программы на C#:
            string code = string.Empty;
            code += "using System;\r\n ";
            code += "namespace CSEvaluator\r\n";
            code += "{ public class Evaluate\r\n";
            code += "  { public  double GetResult()\r\n{double x = " + x + ";\r\n";
            code += " return "+ expression +";\r\n }";
            code += "    private double exp(double x){ return(Math.Exp(x)); }";
            code += "    private double log(double x){ return(Math.Log(x)); }";
            code += "    private double log(double x,double s){ return(Math.Log(x,s)); }";
            code += "    private double pow(double x, double y){ return(Math.Pow(x,y)); }";
            code += "    private double sin(double x){ return(Math.Sin(x)); }";
            code += "    private double cos(double x){ return(Math.Cos(x)); }";
            code += "    private double pi(){ return(Math.PI); }";
            code += "  }\r\n";
            code += "}";
            text += code;

            // компиляция исходного кода и получение сборки
            CompilerResults cr = cs.CompileAssemblyFromSource(cp, code);
            if (cr.Errors != null && cr.Errors.Count > 0) // ? ошибки
            {
                for (int i = 0; i < cr.Errors.Count; i++)
                    text += "Col {0} - {1}" + cr.Errors.Column + cr.Errors.ErrorText;
                return -6666;
            }

            try // создать объект и вызвать метод для вычисления выражения
            {
                object ob = cr.CompiledAssembly.CreateInstance("CSEvaluator.Evaluate");
                return ((double)ob.GetType().InvokeMember("GetResult", BindingFlags.InvokeMethod, null, ob, new object[] { }));
            }
            catch (Exception ex) { text += ex.Message; return (0); }
        }


это функция,


а это вызов из кнопочки:
 
Код:
while (Math.Abs((b - a) / 2) > eps)
            {
                k++;
                x1 = (a + b - sgm) / 2;
                x2 = (a + b + sgm) / 2;
                y1 = computer(expression, convert(x1));
                y2 = computer(expression, convert(x2));
                if (y1 < y2) { b = x2; } else { a = x1; }

            }
63K
29 сентября 2010 года
sanyur
8 / / 28.09.2010
а, простите уже не 12 секунд, а 4...
просто тогда комп был загружен торентами))
5
29 сентября 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: sanyur
а, простите уже не 12 секунд, а 4...
просто тогда комп был загружен торентами))



Т.е. вы "Math.Abs((b - a) / 2) > eps" раз вызываете компиляцию одного и того же выражения? И вы еще спрашиваете, откуда тормоза.
Скомпилируйте выражение один раз и вызывайте его в цикле.

63K
29 сентября 2010 года
sanyur
8 / / 28.09.2010
Цитата: hardcase
Т.е. вы "Math.Abs((b - a) / 2) > eps" раз вызываете компиляцию одного и того же выражения? И вы еще спрашиваете, откуда тормоза.
Скомпилируйте выражение один раз и вызывайте его в цикле.



вы что? в данном случае 20 раз вызываю.

выражение не одно и тоже, я просто не знаю как в компилируемый код засунуть переменную из основного кода.

а потом нужен будет метод ньютона и придется 3 разных кода компилить.
а потом нужен будет метод n-го порядка, придется n+1 код собирать...
ну да ладно, попробуем...
только я не знаю где его вписывать... и еще раз: я просто не знаю как в компилируемый код засунуть переменную из основного кода.
подскажите

5
29 сентября 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: sanyur
я просто не знаю как в компилируемый код засунуть переменную из основного кода.
подскажите

Передайте параметром в конструируемый метод.

63K
29 сентября 2010 года
sanyur
8 / / 28.09.2010
Цитата: hardcase
Передайте параметром в конструируемый метод.



можно примерчик

9.0K
30 сентября 2010 года
t-34
129 / / 30.11.2007
Извините, а почему dll надо именно динамически создавать? Почему нельзя создать обычную длл и вызывать из нее необходимый метод?
Цитата:
а потом нужен будет метод ньютона и придется 3 разных кода компилить.
а потом нужен будет метод n-го порядка, придется n+1 код собирать...


Создайте общий интерфейс IEvaluator для всех классов, производящих вычисление и используйте его вместо кода на кнопочке:

 
Код:
namespace CSEvaluator
{
interface IEvaluator
{
double Evaluate(sometype somevariable);
}
}

 
Код:
namespace CSEvaluator
{
class NewtonMethod : IEvaluator
{
public double Evaluate(sometype somevariable)
{
....
}
}
}

 
Код:
using CSEvaluator; #подключаем длл
...
IEvaluator evaluator = new NewtonMethod();
var someresult = evaluator->Evaluate(some_variable);
63K
02 октября 2010 года
sanyur
8 / / 28.09.2010
я что неправильно выразился? или говорю как то не так?
вы, конечно, меня извините, но при чем тут интерфейс? да, он даст возможность использовать разные методы, но при этом мы будем работать с одной функцией. а нам нужен код, который будет считать рантайм разные функции без парсера, точней используя встроенный разбор шарпа при компиляции кода рантайм.

то есть.. вот можно было написать что то типо
 
Код:
return f(x);
...
double f(double x){return math.sin(x+1)}


Но!!!

нужно такое

 
Код:
double f(string expresion, string argument);


которое еще и говорит, мол, типа вы неправильно ввели выражение, ошибка может быть там то.

и без всяких рекурсивных спусков.

я, конечно понимаю, что по хорошему так делать нельзя, но...


можно написать подобное:

button1_click{сборка. вызов от аргумента х}


но как соединить переменную в "string code" и снаружи - в основном коде?
63K
02 октября 2010 года
sanyur
8 / / 28.09.2010
всем спасиб, сам разобрался
842
05 октября 2010 года
sigmov
301 / / 16.09.2008
Цитата: sanyur
Здравствуйте. помогите повысить быстродействие кода:

Необходимо произвести вычисления минимизации функции. так что данная функция вызывается много раз(например, при методе дихотомии 10 итераций, вызывается 20 раз), а вычисляется минимум функции за 12 секунд. можно ли сократить?

подскажите какая часть кода более трудоемкая.



Наиболее ресурсоемкая - вызов компилятора CSharp.

Сам работал над этой темой когда-то:
http://sources.codenet.ru/file/3604/MathCompiler_3.2.zip
Если надо могу */.cs прислать. Мыло в личку скиньте.

Могу сказать что сравнительно с трансляцией стеком компиляция оправдана при вызове более 50-500 раз.

я что неправильно выразился? или говорю как то не так?
вы, конечно, меня извините, но при чем тут интерфейс?



Вам правильный намек дают.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог