問題タブ [specialized-annotation]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
performance - Scala の標準ライブラリで @specialized なものがほとんどないのはなぜですか?
@specialized
Scala 2.8.1 の標準ライブラリのソース コードでの使用を検索しました。この注釈を使用するトレイトとクラスはほんの一握りのようです: Function0
, Function1
, Function2
, Tuple1
, Tuple2
, Product1
, Product2
, .AbstractFunction0
AbstractFunction1
AbstractFunction2
コレクション クラスはどれも@specialized
. なぜだめですか?これにより生成されるクラスが多すぎますか?
つまり、プリミティブ型でコレクション クラスを使用すると、不要なボックス化とボックス化解除が大量に発生するため、非常に非効率的です。
ボックス化とボックス化解除を回避して、s の不変リストまたはシーケンス (IndexedSeq
特性を含む) を持つ最も効率的な方法は何ですか?Int
scala - 固定サイズで不変の特殊なベクターの実装
パフォーマンスと安全性のために、不変で特殊化された固定サイズのベクトルを実装したいと思います (高速演算が必要です)。私の最初のアイデアは、@specialized
注釈を使用することでした (整数と実数の両方が必要なため)。
これが最初の試みです:
ただし、結果のバイトコードを で分析するjavap
と、要素がまだボックス化されていることがわかります。例えば:
配列はJVMで特殊化されているため、配列は特殊化されていないように見えますが、これはばかげているようです。
目標を達成するためにまだできることはありますか?
scala - リフレクションを介してScalaに特化したフィールドのパラメーターの生のデータ型を取得するにはどうすればよいですか?
特殊なフィールドを持ち、生のデータ型を使用しているクラスがあります。たとえば、Tuple2 [Int、String]:
ここでリフレクションを使用して、「refl」インスタンス内のTuple2の型パラメーターを見つけたいと思います。(フィールドを取得するために「head」を使用して少しごまかします。これが唯一のフィールドであることがわかっているためです。)
これでフィールドができたので、ジェネリック型を照会できます。
ここでの問題は、最初のタイプがオブジェクトであるということです。反射だけで、そのパラメーターの実際の型(Int)を知る方法はありますか?
アップデート:
私はこれを自分のAPI内の自動シリアル化のコンテキストで使用しています。@Serializableでマークされたクラスが与えられた場合、それをシリアル化できます。そのためには、リフレクションを使用してクラスのフィールドとタイプのツリーを再帰的に構築し、深いシリアル化を実行できるようにする必要があります。
@Specializedクラスを直接操作している場合、型は明示的であり、呼び出しサイトでのコンパイル時に認識されているため、機能します。階層内のフィールドが@specializedの場合、リフレクションを介して判断する方法はありません。クラスで宣言されたフィールドまたはメソッドをクエリしても、正しい値は得られません。タイプは実行時に存在しますが、フィールド自体の宣言ではなく、フィールドに保持されているインスタンスにのみ存在します。したがって、インスタンスがnullで、「getClass」を実行できない場合、リフレクションだけでは正しいタイプを知ることができません。
java - Scala(またはJava)でのジェネリック関数の専門化
Scalaでジェネリック関数(またはクラス)を特殊化することは可能ですか?たとえば、データをByteBufferに書き込むジェネリック関数を記述したいとします。
ただし、putメソッドは1バイトしか使用せず、それをバッファーに入れるため、次のようにIntとLongsに特化する必要があります。
コンパイルされません。もちろん、代わりに3つの異なる関数writeByte、writeInt、writeLongをそれぞれ書き込むこともできますが、配列に別の関数があるとしましょう。
これは、特殊なwriteData関数がないと機能しません。別の関数のセットwriteByteArray、writeIntArray、writeLongArrayをデプロイする必要があります。タイプに依存する書き込み関数を使用する必要があるときはいつでも、この状況に対処しなければならないのはクールではありません。私はいくつかの調査を行いましたが、考えられる回避策の1つは、パラメーターのタイプをテストすることです。
これは機能する可能性がありますが、特殊な機能バージョンとは異なり、タイプチェックは実行時に実行されるため、効率が低下します。
だから私の質問は、ScalaまたはJavaでこの種の問題を解決するための最も望ましくて好ましい方法は何ですか?よろしくお願いします!
scala - Scalaに特化したパターンマッチング
Double と Float で動作する必要があるクラスがあります。パフォーマンス要件のために、@specialized
アノテーション付きのジェネリックを使用します。(Double, Float)
呼び出す必要があるサードパーティ関数が 2 つあります。ffunc(x: Float)
受け入れますFloat
、dfunc(y: Double)
受け入れますDouble
。ある時点で、またはのいずれかを呼び出すffunc
必要がありdfunc
ます。そのために、scala パターン マッチングを使用します。私のコードは次のようになります。
ただし、scala コンパイラは、特殊化されたバージョンに対して最適化されていないバイトコードを提供します。特殊化されたクラスのバイトコードの内部を見ると、特殊化された型をオブジェクトに変換する最適化されていない一致するコードが表示されます。次のように、追加のボックス化/ボックス化解除もあります。
一致するコードを、最適化され、ボックス化/ボックス化解除を回避するコードに置き換えることを提案できますか?
scala - 関数の Scala @specialized アノテーションは、パターン マッチングで特殊化された型を生成しません
私はscalaに次の関数を持っています。それを使用して、トラバース可能を配列に変換し、トラバース可能でないものを配列でラップします。
https://issues.scala-lang.org/browse/SI-6967を回避するために @specialized アノテーションが追加されました。つまり、プリミティブ型がパターン マッチングに失敗する可能性がある scala 2.10 のバグです。
ただし、コンパイラは次のエラーを表示しました。
v: T は特殊な実装では (Any ではなく) double 型の変数である必要があるため、これは奇妙です。私はどこで間違ったのですか?
scala - scala で特殊な値クラスの効果を得ることができますか?
私は@specialized
クラスと値クラスがどのように機能するかを知っており、次のような特殊な値クラスを持つことはできないことを知っています:
同様の効果を得る方法が見つかりません。単一の宣言で、複数の Java プリミティブに対する純粋な構文ラッパーとして機能するユーザー型/型コンストラクターを作成します。この制限を回避する方法はありますか?
値クラスの背後にある主な動機の 1 つは、ビジネス上の意味を持つ値型に「注釈を付け」、そのデータの型とは異なる型を作成することでした。
ボックス化されたタイプを静的に知っている限り、これは非常にうまく機能しますが、いくつかの異なるプリミティブをミリボルトとして扱いたい場合は、プリミティブごとに新しいラッパーを作成するか、それらが設計されたものにジェネリックを使用するオプションがありますに:
これはすべて甘いもので、実際にof
ラッパーはコンパイル時に削除されますが、残念ながらプリミティブは Java ラッパーにボックス化され、2 つのフィールドは次のようにコンパイルされます。
long
およびint
フィールドではありません。
次のようなコードを書くことは可能ですか?
- 単一の宣言(新しい「ユニット」タイプ)で新しいそのようなラッパーを作成できます。
- 少なくとも基礎となるプリミティブ (ミリボルトで動作するメソッド、ボックス化されたプリミティブからの抽象化) に関して、そのようなラッパーで一般的な操作を実行します。
- ラッパー型と基になるプリミティブ型の両方が完全にインスタンス化され (ジェネリック型の型パラメーターではない)、呼び出されたメソッドをインライン化できる場合は、ボクシングを実行しません (したがって、現在および将来のすべてのユニットに対して追加を 1 回定義できます)。
- 理想的には、クライアント コードのマクロに依存しません (型宣言自体が IDE で理解できる限り、実装での使用は問題ありません)。
scala - 呼び出し時にテンプレート パラメータが既知のテンプレート ベースで @specialized のメリットはありますか?
私が持っているとします:
ボックス化/ボックス化解除は次のいずれかの場合に発生しますか? @specialized はそれを回避しますか?
特殊化しない場合、d2.apply の呼び出しは Double または Object を受け取りますか?
実現可能:
前者は、コンパイラがコンパイル時に証明できるため、apply メソッドの型は double です。
後者は、DoubleNormalizer.apply(Double) が Normalizer.apply(Object) の実装であり、apply(Object) が JVM が提供する唯一の具象型シグネチャであるためです。