标签: runtime-compilation

运行时代码生成和编译

假设我有这段代码,它使用一些输入(例如 URL 路径)来通过反射来确定要运行的方法:

// init
map.put("/users/*", "viewUser");
map.put("/users", "userIndex");

// later
String methodName = map.get(path);
Method m = Handler.class.getMethod(methodName, ...);
m.invoke(handler, ...);
Run Code Online (Sandbox Code Playgroud)

这使用反射,因此可以提高性能。可以这样做:

// init
map.put("/users/*", new Runnable() { public void run() { handler.viewUser(); } });
map.put("/users", new Runnable() { public void run() { handler.userIndex(); } });

// later
Runnable action = map.get(path);
action.run();
Run Code Online (Sandbox Code Playgroud)

但手动创建所有这些Runnable都有其自身的问题。我想知道,我可以在运行时生成它们吗?因此,我将拥有第一个示例中的输入映射,并动态创建第二个示例的映射。当然,生成它只是构建一个字符串的问题,但是编译和加载它呢?

注意:我知道性能提升很小,这是过早优化的完美例子。因此,这是一个学术问题,我对运行时生成和代码编译感兴趣。

java code-generation javac runtime-compilation classloader

5
推荐指数
1
解决办法
5770
查看次数

使用 Roslyn 解析运行时生成类型的 lambda 表达式

我正在尝试使用 Roslyn 作为解析用户在运行时使用通用格式提供的 lambda 表达式的一种方式:

// The first line is normally static and re-used across callers to save perf
Script baseScript = CSharpScript.Create(string.Empty, scriptOptions);
ScriptState<T> scriptState = await baseScript.ContinueWith<Expression<Func<T, bool>>>(code, scriptOptions).RunAsync()
var parsedExpression = scriptState.ReturnValue;
Run Code Online (Sandbox Code Playgroud)

然后调用者提供code类似P => P.Property > 5. 当我为 T 使用众所周知的类型时,这一切都很好,但我希望允许用户使用更多动态类型,其中每个用户都可以定义自己的一组属性(带有类型)。同步表达式树不支持动态类型(因此 Roslyn 无法编译),我希望允许用户定义他们的属性,并且我会动态生成运行时类型。

我遇到的问题是,在创建运行时类型后,我没有具体的类型可用于Tin .ContinueWith<Expression<Func<T,bool>>>

我使用 full on 反射做类似的事情:

var funcType = typeof(Func<,>).MakeGenericType(runtimeType, typeof(bool));
var expressionType = typeof(Expression<>).MakeGenericType(funcType);

var continueWith = script.GetType()
    .GetMethods()
    .Single(m => m.Name == "ContinueWith" && m.IsGenericMethod && …
Run Code Online (Sandbox Code Playgroud)

c# runtime-compilation roslyn

5
推荐指数
1
解决办法
1095
查看次数

在泛型类中创建的Func &lt;string&gt;调用RuntimeHelpers.PrepareMethod时不起作用

我目前正在对Moq框架进行扩展,以模拟非虚拟方法的实现。目前,我已经通过获取原始方法的方法句柄并将其与用户定义的Func的指针进行交换来进行此工作。

我仍然遇到的一个问题是,当我在Moq内部代码中(在使用泛型的类中)创建Func时,遇到了RuntimeHelpers.PrepareMethod的问题。(在执行指针交换之前,需要准备Func)。

当我在普通类(例如Program)中创建完全相同的Func时,一切正常。

进一步调查该问题可以追溯到调用类是否具有通用参数。

抛出异常:

An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll

Additional information: The given generic instantiation was invalid.
Run Code Online (Sandbox Code Playgroud)

我在以下代码块中隔离了该问题:

class Program
{
    static void Main(string[] args)
    {
        new WithoutGeneric().GoExecute();
        new WithGeneric<string>().GoExecute();
    }
}

public class WithoutGeneric
{
    public void GoExecute()
    {
        //Works fine
        StaticMethods.PrepareThisFunc(() => "Test");
    }
}

public class WithGeneric<T>
{
    public void GoExecute()
    {
        //Breaks
        StaticMethods.PrepareThisFunc(() => "Test");
    }
}

public static class StaticMethods
{
    public static void PrepareThisFunc(Func<string> theFunc)
    {
        RuntimeHelpers.PrepareMethod(theFunc.Method.MethodHandle);
    }
} …
Run Code Online (Sandbox Code Playgroud)

.net c# reflection il runtime-compilation

4
推荐指数
1
解决办法
1103
查看次数

在运行时确定String中Java表达式的返回类型

在运行时,在我的Java程序中,给定一个String,我想知道返回类型.例如:

  • 1 + 1 回报 int
  • 1L + 1L 回报 long
  • 1L + 1 回报 long
  • 1 + 1.5 回报 double
  • 1 + 2 - 3 * 4 / 5 回报 int
  • 1 / 0 回报 int
  • 1 + Math.nextInt() 回报 int
  • 1.5 + Math.nextInt() 回报 double
  • Color.RED 回报 java.awt.Color
  • 鉴于这a是一个int:a + 1returnint
  • 鉴于这a是一个int:a + 1.5returndouble

没有必要实际评估代码:我只需要返回类型.如何使用JDK运行时编译器,ECJ JDT或任何其他纯Java依赖项执行此操作?


详细代码:以下是此代码的简化伪代码单元测试:

public static void ExpressionTyper {
    public String determineType(String expression, Map<String, …
Run Code Online (Sandbox Code Playgroud)

java reflection runtime-compilation ecj

4
推荐指数
1
解决办法
170
查看次数

如何加快Common Lisp`IF`语句的编译速度?

我有一个生成决策树,并将它们转换成嵌套Common Lisp的系统if与谓词检查,如果一个变量的值的语句>=或者<=一个给定的整数如

(LAMBDA (V1 V2)
  (IF (>= V1 2)
      (IF (<= V1 3)
          (IF (<= V2 3)
              (IF (>= V2 2) 16 (IF (>= V2 1) 6 0))
            (IF (<= V2 4) 10 0))
        (IF (<= V1 4)
            (IF (>= V2 1) (IF (<= V2 3) 6 0) 0)
          0))
    (IF (>= V1 1)
        (IF (>= V2 2) (IF (<= V2 4) 10 0) 0)
      0)))
Run Code Online (Sandbox Code Playgroud)

然后我使用eval编译Lisp代码,生成比解释原始决策树更快的函数.尽管如此,这个编译步骤需要花费相当长的时间:具有5000个嵌套ifs的函数需要花费一分钟来编译(在powerbook上的Clozure Common Lisp中),即使生成if语句需要大约100毫秒.为什么这么简单的结构需要这么长时间?有什么我可以做的大幅加快,一些声明可能吗?我非常感谢您提供的任何指示.

performance if-statement common-lisp runtime-compilation clozure-cl

4
推荐指数
1
解决办法
91
查看次数

加载外部源代码并在内部使用它们(通过重新编译或其他东西)

有没有办法使用外部存储的源代码并将其加载到Java程序中,以便它可以被它使用?

我希望有一个程序可以在不编辑完整源代码的情况下进行更改,甚至可以在不编译每次的情况下进行更改.另一个优点是,我可以像我想要的那样更改部分代码.

当然,我必须有接口,以便可以将数据发送到此并再次将其恢复到固定源程序.

当然,它应该比纯粹的口译系统更快.

那么这样做是否有一种方法可以像这些外部源代码部分的额外编译以及完成后的程序启动一样?

提前谢谢你,Andreas :)

java resources runtime-compilation

3
推荐指数
1
解决办法
1539
查看次数

运行时期间构造函数的数量和java.math.BigDecimal的编译时间不匹配

我定义了一个名为BigDecimalWithAttrDisplay的新类,具有以下实现:

class BigDecimalWithAttrDisplay extends BigDecimal{
    String display;
    BigDecimalWithAttrDisplay(String val){super(val)}
    public String toString(){
        "BigDecimalWithAttrDisplay{val=${super.toString()}, display='$display'}";
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试运行使用此类的代码时,我得到:

java.lang.IncompatibleClassChangeError: the number of constructors during runtime and compile time for java.math.BigDecimal do not match. Expected 17 but got 18
at groovy.lang.MetaClassImpl.selectConstructorAndTransformArguments(MetaClassImpl.java:1381)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.selectConstructorAndTransformArguments(ScriptBytecodeAdapter.java:234)
at com.e4x.auto.services.checkout.testapi.model.response.BigDecimalWithAttrDisplay.<init>(BigDecimalWithAttrDisplay.groovy:31)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:71)
at org.codehaus.groovy.runtime.callsite.ConstructorSite.callConstructor(ConstructorSite.java:42)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:194)
Run Code Online (Sandbox Code Playgroud)

有什么问题,我该如何解决?

java groovy exception runtime-compilation

2
推荐指数
1
解决办法
4491
查看次数

Lambda编译抛出"从范围引用''类型的"变量",但它没有定义"

当我尝试编译下面显示的lambda时,它抛出:

类型为'System.Collections.Generic.IEnumerable`1 [WheelEndCatalogKendo.Models.SapBasicData]'的变量'model''从范围''引用,但未定义

public static GridBoundColumnBuilder<TModel> BuildColumnString<TModel>(this GridBoundColumnBuilder<TModel> column, WebViewPage<IEnumerable<TModel>> webViewPage, int width) where TModel : class {
    var modelParameter = Expression.Parameter(typeof(IEnumerable<TModel>), "model");
    Expression<Func<IEnumerable<TModel>, TModel>> firstItem = (model) => model.FirstOrDefault();
    var member = MemberExpression.Property(firstItem.Body, column.Column.Member);
    var lambda = Expression.Lambda<Func<IEnumerable<TModel>, string>>(member, modelParameter);
    var title = webViewPage.Html.DisplayNameFor(lambda).ToHtmlString();
    var header = webViewPage.Html.ShortLabelFor(lambda).ToHtmlString().FixUpNewLinesAsHtml();
    var compiled = lambda.Compile(); //Throws here with "variable '...' of type '...' referenced from scope '', but it is not defined"
....
}
Run Code Online (Sandbox Code Playgroud)

我看到几个类似的帖子; 但到目前为止,他们还没有告诉我我的代码问题.看起来我正在提供lambda变量(作为第二个参数参数).然而,我几乎没有创作表达树的经验.

有任何想法吗?

c# runtime-compilation expression-trees

2
推荐指数
1
解决办法
4973
查看次数

在 Core3.1 中安装 Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 时,项目必须提供配置错误值

当我在 Web 项目中安装Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation并在启动中添加:

 services.AddMvc().AddRazorRuntimeCompilation();
Run Code Online (Sandbox Code Playgroud)

,项目无法运行,错误为:

项目必须提供配置值

我的.NET-Core版本是3.1

如何解决这个问题?

runtime-compilation razor asp.net-core

2
推荐指数
1
解决办法
1501
查看次数

什么是时间复杂度?

以下功能的时间复杂度是多少?

    for(int i = 0; i < a.size; i++) {
        for(int j = i; j < a.size; i++) {
            //
        }
    }
Run Code Online (Sandbox Code Playgroud)

我认为它不是大O n ^ 2因为我们没有迭代第二个for循环中的所有元素.我相信时间的复杂性是这样的:

n[ (n) + (n-1) + (n-2) + ... + (n-n) ]
Run Code Online (Sandbox Code Playgroud)

但是,当我解决这个公式时,它就会出现

n^2 - n + n^2 - 2n + n^2 - 3n + ... + n^2 - n^2
Run Code Online (Sandbox Code Playgroud)

这根本不正确.有人能告诉我究竟如何解决这个问题,以及我错在哪里.

algorithm big-o runtime-compilation time-complexity

1
推荐指数
1
解决办法
173
查看次数

依赖项注入自定义文件提供程序以进行运行时编译

我正在尝试从数据库加载视图,正如文章中所建议的,人们可能想要添加一些缓存以防止每次都访问数据库。

ConfigureServices

services.AddHttpContextAccessor();
services.AddMemoryCache();

services.AddRazorPages()
    .AddRazorRuntimeCompilation(opt =>
    {
        opt.FileProviders.Add(new DatabaseFileProvider(Configuration["AppSettings:SQLConnectionString"]));
    });
Run Code Online (Sandbox Code Playgroud)

DatabaseFileProvider构造函数:

private string _connection;

public DatabaseFileProvider(string connection)
{
    _connection = connection;
}
Run Code Online (Sandbox Code Playgroud)

如何将 的实例依赖注入IMemoryCacheDatabaseFileProvider类中?就像使用单例一样:

ConfigureServices

services.AddSingleton<AppUtils>();
Run Code Online (Sandbox Code Playgroud)

AppUtils构造函数:

private static IMemoryCache _cache;

public AppUtils(IMemoryCache cache)
{
    _cache = cache;
}
Run Code Online (Sandbox Code Playgroud)

c# dependency-injection runtime-compilation fileprovider asp.net-core-5.0

1
推荐指数
1
解决办法
972
查看次数

在编译时阻塞运算符 ==()

我有一个 ID-Record 类,我想阻止调用者/用户使用运算符==,因为它不明确(用户可能只想比较数据字段是否相等)。

这是我的班级:

#include <string>
#include <functional>

class ID_Record
{
  public:
    bool operator==(const ID_Record& other) const
        {  throw std::bad_function_call(); }
    unsigned int id;  // Record ID used for database.
    std::string  value;
};
Run Code Online (Sandbox Code Playgroud)

我更喜欢operator==()在编译时“阻止”,这样编译器就可以捕获它而不是在运行时捕获它。

编译器应该为此代码生成错误:

ID_Record a(6, "Tree");
ID_Record b(3, "Platinum");
if (a == b) std::cout "Records are equal\n"; // This line should fail compilation.
Run Code Online (Sandbox Code Playgroud)

我也想阻止编译器生成的功能的情况。

c++ operator-overloading runtime-compilation

0
推荐指数
1
解决办法
123
查看次数

如何解决"预期"; 在C中的'{'token'之前?

我创建了一个打印罗马相当于一年的程序,但是我的程序显示了一个编译错误.我的节目说:

33 4 C:\ Users\ABC\Desktop\cc [Error] expected';' 在'{'之前

这是我的代码:

#include<stdio.h>
main()
{
    int a,rom;
    printf("Enter the year.");
    scanf("%d",&a);
    rom=reverse(a);
    printf("Roman equivalent of %d is:",a);
}
reverse(int a)
{
    int i,rev=0,rem;
    for(i=a;i>0;i=i/10)
    {
        rem=i%10;
        rev=rev*10+rem;
    }
    roman(a);
}
roman(int a)
{
    int c=0,i,j,k,l,m;
    for(i=a;i>0;i=i/10)
    {
        m=i%10;
        for(j=1;j>0;j--)
        {
            if(c==0)
            {
                printf("m\n");
            }
            elseif(c==1)
            {
                printf("d\n");
                for(l=m-5;l>0;l--)
                    printf("c");
                printf("\n");
            }
            elseif(c==2)
            {
                printf("l\n");
                for(l=m-5;l>0;l--)
                {
                    printf("x");
                }
                printf("\n");
            }
            elseif(c==3)
            {
                printf("v\n");
                for(l=m-5;l>0;l--)
                {
                    printf("i");
                }
                printf("\n");
            }
        }
        c++;
    }
}
Run Code Online (Sandbox Code Playgroud)

c compiler-errors compilation runtime-compilation

-4
推荐指数
1
解决办法
1972
查看次数