| Author |
Message |
|
| bkl |
Posted: Fri Apr 09, 2010 6:16 am |
|
|
|
User
Joined: 17 Aug 2008
Posts: 19
|
I want to pass an (2 byte) integer via command-line, e.g.
erl -MyInstanceId 3 -s myapp
This integer constant will then be used by several low level functions
to do some data encoding stuff. Since this constant is used very
frequently, I wonder if using init:get_arguments() is a good way to
acquire this value every time.
Is there any other way to store a globally-visible-constant value in
Erlang? I vaguely remembered there is a trick of compiling a small
runtime generated code and load it at init time. Will that be more
efficient and where can I find a sample code for that?
Thanks in advanced,
Bkl |
|
|
| Back to top |
|
| Michal Ptaszek |
Posted: Fri Apr 09, 2010 11:16 am |
|
|
|
User
Joined: 01 May 2008
Posts: 35
Location: Krakow
|
You can also use:
* application environment variables (application:get_env/2)
* compilation time macro definition (http://www.erlang.org/doc/man/compile.html => {d, Name, Val})
* as you mentioned - runtime code generation (take a look at the ejabberd's ejabberd_loglevel.erl)
* public, named ets tables |
|
|
| Back to top |
|
| bkl |
Posted: Fri Apr 09, 2010 5:12 pm |
|
|
|
User
Joined: 17 Aug 2008
Posts: 19
|
Michael,
Thanks for the reply. I took a look at the OTP source.
- application:get_env() is basically using ETS to find the
application-specific configuration value using the process
group leader's PID as index key into ETS.
- "compilation time macro definition", my understanding is
that the macro definition will expand at compile time.
For my case, I need to run several instances of Erlang
each with different runtime value of "-MyInstanceId". So
that won't work, unless I have several copies of
compiled code...
I will take a look at the ejabberd_loglevel.erl.
Also, I have question about efficiency in these approaches.
My guess is that dynamic compilation is probably the most
efficient route. Is that assumption correct?
Bkl |
|
|
| Back to top |
|
| bkl |
Posted: Fri Apr 09, 2010 5:19 pm |
|
|
|
User
Joined: 17 Aug 2008
Posts: 19
|
Correction. On 2nd thought, I think the compiled MACRO
approach should be THE most efficient one. Actually, I am
curious. Comparing with hard-coded-compiled constant value,
how efficient is the dynamically-compiled function stub with
arity of 0. I guess the difference should be just a direct
memory reference against a JUMP plus PUSH and POP of the value,
right?
Bkl |
|
|
| Back to top |
|
| jwatte |
Posted: Fri Apr 09, 2010 5:54 pm |
|
|
|
User
Joined: 10 Feb 2010
Posts: 34
|
You can use parameterized modules and make the small integer be an argument to the module. As far as I can tell, that should be similar in efficiency to creating the work procedure as a fun(), for example.
However, if efficiency of number crunching is your requirement -- why use Erlang? |
|
|
| Back to top |
|
| bkl |
Posted: Fri Apr 09, 2010 8:23 pm |
|
|
|
User
Joined: 17 Aug 2008
Posts: 19
|
jwatte,
I'm not sure if parameterized module (PM) is a solution. Unless I
misunderstood the semantics of PM, but you have to instantiate the PM
EVERY TIME in your code before you can use them. If so, there is a
chicken-and-egg question of how do you get the parameter value
(i.e. "MyInstanceId") in the first place, which is my original
question.
As to "efficiency of number crunching", the data encoding stuff is
only a very small but necessary part of my project. I'm using
all the other wonderful things in Erlang, and only scratch my head for
this tiny little easily-solvable-by-global-memory-pointer-in-C problem
... |
|
|
| Back to top |
|
| jwatte |
Posted: Fri Apr 09, 2010 9:09 pm |
|
|
|
User
Joined: 10 Feb 2010
Posts: 34
|
Let's assume you have some kind of calculation:
Let's asssume this calculation is based on "MyInstanceId."
Code: -module(calculator, [MyInstanceId]).
my_calculating_function() -> ...
Then you would make MyInstanceId a parameter of the module where my_calculating_function() lives, and you'd start the calculation from another module:
Code: start_calculation() ->
Module = calculator:new(application:get_env(instance_id)),
Module:my_calculating_function().
Note that you only need to read the instance ID once, when you instantiate the module. You then have the module instance in your Module variable, and call it directly. |
|
|
| Back to top |
|
| bkl |
Posted: Sat Apr 10, 2010 3:28 am |
|
|
|
User
Joined: 17 Aug 2008
Posts: 19
|
jwatte,
Ah, I see what you are saying. So, this is as if the parameter
"MyInstanceId" becomes a "locally global" variable within the PM. But,
if I understand correctly, for this approach I still have to:
1. carry this Module variable around so that I can keep this
instantiated Module around.
2. either I need to refactor and consolidate all the low level
functions that needs to access "MyInstanceId" into one module, or I
need to parameterize all of the accessing modules.
3. for any process I spawn later, or any function call that needs
Module, I will need to pass the Module as a parameter to them.
I guess PM only addresses part of my original problem, which requires
a mechanism to mimic "globally accessible" constant... |
|
|
| Back to top |
|
| jwatte |
Posted: Mon Apr 12, 2010 5:03 pm |
|
|
|
User
Joined: 10 Feb 2010
Posts: 34
|
Often, the fact that a given constant is needed in a lot of places means that the system is factored across some boundaries that don't actually match up with the needs of the system. If that is the case, you'd need to re-factor your system :-)
If that's not an option, then I would suggest what was suggested above: use a named ETS table. ETS is the same storage engine used by Erlang internally for variables, so it's about as efficient as you can get for dynamic look-up, except the dynamic look-up of the named ETS table for each access is still a small performance hit. You can hide the ets access behind a macro. (We use this for stubbing services in unit testing, but not for individual quantities)
I would not rely on application:get_env() to be as efficient as direct ETS access.
Although, again: if performance in the small is that important, Erlang might not be the right language choice. |
|
|
| Back to top |
|
| bkl |
Posted: Wed Apr 14, 2010 8:06 pm |
|
|
|
User
Joined: 17 Aug 2008
Posts: 19
|
Jwatte,
I agree I probably need some refactoring independent of whether I am using PM or not . What I found after coding in Erlang ~ 2 years is that Erlang seems to "force" the programmer to constantly refactor the code, which, for most of the time, is a good thing.
Regarding ETS, how is that compared with dynamic compilation approach? On one hand ets:lookup is a BIF, on the other hand, once compiled and linked, the my_hook:getMyInstance() call should be very efficient too, right?
Ben |
|
|
| Back to top |
|
| Michal Ptaszek |
Posted: Thu Apr 15, 2010 9:40 am |
|
|
|
User
Joined: 01 May 2008
Posts: 35
Location: Krakow
|
| Please correct me if I'm wrong: I think parametrized modules are not a documented feature, thus they might change in any time. I would not recommend to use them if you prepare a code that should be ran on the production and which you would like to upgrade to new releases in the future. |
|
|
| Back to top |
|
| wuji |
Posted: Tue Aug 14, 2012 7:52 am |
|
|
|
User
Joined: 10 Aug 2012
Posts: 654
|
for information leading to the capture of Miguel Angel and and cheap polo ralph lauren and Omar.The brothers, whose numeric aliases refer to their alleged
within the Zetas at the time of the cartel's creation creation [h4]jordan 6[/h4] creation several years ago, are now allegedly top leaders of
organization that controls drug trafficking in the east and south south [h4]cheap jordans[/h4] south of Mexico. Miguel, or "40," allegedly runs the Zetas
with "3," Heriberto Lazcano.The Zetas began in 1999 when former former jordan 6 former members of the Mexican military signed on to work
security for the Gulf drug cartel. The Zetas went into into knockoff designer *beep* into business for themselves and are now at war with |
|
|
| Back to top |
|
|
|