Conversion of integer -> char - scheme

I'm learning scheme and I stumbled upon this in a textbook:
(integer->char 50) ⇒ #\2
Why does integer->char 50 evaluate to 2? Is it because "50" is too big to be a character, so it just takes the length/number of digits?

It doesn't evaluate to 2: it evaluates to the character #\2, which is a completely different thing:
> (for ([i (in-range 32 128)])
(let ([c (integer->char i)])
(printf "~S: ~S / '~A'~%" i c c)))
32: #\space / ' '
33: #\! / '!'
34: #\" / '"'
35: #\# / '#'
36: #\$ / '$'
37: #\% / '%'
38: #\& / '&'
39: #\' / '''
40: #\( / '('
41: #\) / ')'
42: #\* / '*'
43: #\+ / '+'
44: #\, / ','
45: #\- / '-'
46: #\. / '.'
47: #\/ / '/'
48: #\0 / '0'
49: #\1 / '1'
50: #\2 / '2'
51: #\3 / '3'
52: #\4 / '4'
53: #\5 / '5'
54: #\6 / '6'
55: #\7 / '7'
56: #\8 / '8'
57: #\9 / '9'
58: #\: / ':'
59: #\; / ';'
60: #\< / '<'
61: #\= / '='
62: #\> / '>'
63: #\? / '?'
64: #\# / '#'
65: #\A / 'A'
66: #\B / 'B'
67: #\C / 'C'
68: #\D / 'D'
69: #\E / 'E'
70: #\F / 'F'
71: #\G / 'G'
72: #\H / 'H'
73: #\I / 'I'
74: #\J / 'J'
75: #\K / 'K'
76: #\L / 'L'
77: #\M / 'M'
78: #\N / 'N'
79: #\O / 'O'
80: #\P / 'P'
81: #\Q / 'Q'
82: #\R / 'R'
83: #\S / 'S'
84: #\T / 'T'
85: #\U / 'U'
86: #\V / 'V'
87: #\W / 'W'
88: #\X / 'X'
89: #\Y / 'Y'
90: #\Z / 'Z'
91: #\[ / '['
92: #\\ / '\'
93: #\] / ']'
94: #\^ / '^'
95: #\_ / '_'
96: #\` / '`'
97: #\a / 'a'
98: #\b / 'b'
99: #\c / 'c'
100: #\d / 'd'
101: #\e / 'e'
102: #\f / 'f'
103: #\g / 'g'
104: #\h / 'h'
105: #\i / 'i'
106: #\j / 'j'
107: #\k / 'k'
108: #\l / 'l'
109: #\m / 'm'
110: #\n / 'n'
111: #\o / 'o'
112: #\p / 'p'
113: #\q / 'q'
114: #\r / 'r'
115: #\s / 's'
116: #\t / 't'
117: #\u / 'u'
118: #\v / 'v'
119: #\w / 'w'
120: #\x / 'x'
121: #\y / 'y'
122: #\z / 'z'
123: #\{ / '{'
124: #\| / '|'
125: #\} / '}'
126: #\~ / '~'
127: #\rubout / ''

It's important to know that it does not convert a numeric value to it's digit, rather it converts the ascii value to its corresponding character. Eg. the ascii value 50 represents the character #\2 (digit 2) and 65 represents #\A (capital letter A).
You find the documentation in the report:
procedure: (char->integer char)
procedure: (integer->char n)
Given a character, char->integer returns an exact integer
representation of the character. Given an exact integer that is the
image of a character under char->integer, integer->char returns that
character.
Scheme has a procedure called number->string which converts a number to a string representation:
(number->string 50 10) ; ==> "50" (base 10 representation)
(number->string #x32 10) ; ==> "50" (base 10 representation)
(number->string 50 16) ; ==> "32" (hex, base 16)

Related

Extract hours from time

I am try to find solution but I couldn't. The problem is following.
1 ) I want to extract hours from time and add minutes converted to hours
(SUM(SUBSTRING_INDEX(aa.Quantity, ':', 1)) + TRUNCATE((SUM(SUBSTRING_INDEX(aa.Quantity, ':', -1)) / 60),0))
So for example If I have 16hours:35minutes. I want to display 16 and minutes part should be added to hours as 16,5 hours for example
2) extract minutes from time and find reminder (modulo)
LPAD((SUM(SUBSTRING_INDEX(aa.Quantity, ':', -1)) % 60), 2, 0)
I found this part of solution but this soulution is wrote in MySQL and I need Oracle SQL solution
CONCAT(
-- extract hours froAm time and add minutes converted to hours
(SUM(SUBSTRING_INDEX(aa.Quantity, ':', 1)) + TRUNCATE((SUM(SUBSTRING_INDEX(aa.Quantity, ':', -1)) / 60),0))
, ':',
-- extract minutes from time and find reminder (modulo)*/
LPAD((SUM(SUBSTRING_INDEX(aa.Quantity, ':', -1)) % 60), 2, 0)
) AS W_TOTAL_SUM
Also I try to convert this MySQL statment to Oracle SQL by using following site, but unfortunettly I didn't get correct result since it returns same output as input
http://www.sqlines.com/online
So exactly same as I decribe but only in Oracle SQL. I would be very thankfull since I try to fix this problem a couple of hours and couldn't find any solution for this problem
Here is my solution which doesn't work. I get error
ORA-00907: missing right parenthesis
SELECT
(SUM(SUBSTR(A.Quantity, ':', 1)) + TRUNC((SUM(SUBSTR(A.Quantity, ':', -1)) / 60),0)), ':' ,
MOD(LPAD(SUM(SUBSTR(A.Quantity, ':', -1)), 60),2,0)
-- MOD(LPAD((SUM(SUBSTRING_INDEX(A.Quantity, ':', -1)) % 60), 2, 0)
-- LPAD((SUM(SUBSTRING_INDEX(aa.Quantity, ':', -1)) % 60), 2, 0)
AS TOTAL_SUM FROM (
SELECT
ata.ATAID AS AtaId, ata.ProjectID, ata.StartDate, ataAW.Quantity
FROM
ata
INNER JOIN
weekly_report
ON
weekly_report.ataId = ata.ATAID
INNER JOIN
ata_articles ataAW
ON
ataAW.wrId = weekly_report.id
WHERE
ata.ATAID = 10987
AND
ataAW.type = 1
OR
ataAW.type = 2
OR
ataAW.type = 3
AND
(weekly_report.status != 3 AND weekly_report.status != 4)
AND
(
weekly_report.year < (SELECT year FROM weekly_report WHERE id = 89)
OR
(
weekly_report.year <= (SELECT year FROM weekly_report WHERE id = 89)
AND
weekly_report.week <= (SELECT week FROM weekly_report WHERE id = 89)
)
)
) A
group by A.AtaId
order by A.AtaId ASC
The common problem is
LPAD((SUM(SUBSTR(A.Quantity, ':', -1)) MOD 60), 2, 0)
Here is output which I expect
TOTAL_SUM
101:24
This is how I understood the question:
sample data in lines #1 - 2
extract hours (line #3)
extract minutes (line #5), divide it by 60 (as number of minutes in an hour)
hours + minutes = result
SQL> with test (col) as
2 (select '16hours:35minutes' from dual)
3 select to_number(regexp_substr(col, '\d+', 1, 1)) -- hours
4 +
5 round(to_number(regexp_substr(col, '\d+', 1, 2)) / 60, 2) -- minutes
6 as result
7 from test
8 /
RESULT
----------
16,58
SQL>

Weird TypeError about the bisector and concaving the sun

I'm tryna make a random username generator (or at least a prototype)
Code I'm using is This:
def Usergenerator():
word1 = {
0: 'Good',
1: 'I',
2: 'yeet',
3: 'Not',
4: 'Fishe',
5: 'Xx',
6: 'Ucan',
7: 'Ultra',
8: 'Bald',
9: 'boom',
10: 'silly'
}
word2 = {
0: 'Milk',
1: 'Cat',
2: 'Dog',
3: 'poo',
4: 'ghost',
5: 'Fire',
6: 'xX',
7: 'June',
8: 'Lunar'
}
word3 = {
0: 'Foot',
1: 'Man',
2: 'Boy',
3: 'Poop',
4: 'Cell',
5: 'Wat',
6: 'Burn'
}
numbers = {
0: '12',
1: '60',
2: '45',
3: '11',
4: '22',
5: '33',
6: '78',
7: '16',
8: '55'
}
import random
a = 0
b = len(word1)
random = random.randint(a, b)
get = word1.get(random)
import random
a = 0
b = len(word2)
random = random.randint(a, b)
get2 = word2.get(random)
import random
a = 0
b = len(word3)
random = random.randint(a, b)
get3 = word3.get(random)
import random
a = 0
b = len(numbers)
random = random.randint(a, b)
get4 = numbers.get(random)
Username1 = get + get2 + get3 + get4
print(Username1)
Usergenerator()
The dictionaries maps numbers from 0 to whatever to a word
There are multiple that have different mappings and lengths
it first imports random, then generates a random number, and maps the random number onto the word
Then it sets "get" to the result
it does this about 4 times
Then it combines all of the give variables into one, called "Username"
then just prints Username out
this is all in a module which is then ran after its created
But I get this error:
File "c:/Users/why/are/you/here/you/creep.py", line 85, in Usergenerator
Username1 = get + get2 + get3 + get4
TypeError: can only concatenate str (not "NoneType") to str"
Turns out you have to format it so I had to do this:
Username = f'{get}{get2}{get3}{get4}'
print(Username)
I just answered my own question

Understanding blocks in gcov files

I'm trying to understand the output of the gcov tool. Running it with -a options makes sense, and want to understand the block coverage options. Unfortunately it's hard to make sense of what the blocks do and why they aren't taken. Below is the output.
I have run add function in my calculator program once. I have no clue why it shows block0.
-: 0:Source:calculator.c
-: 0:Graph:calculator.gcno
-: 0:Data:calculator.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include "calculator.h"
-: 2:#include <stdio.h>
-: 3:#include <stdlib.h>
-: 4:
1: 5:int main(int argc, char *argv[])
1: 5-block 0
-: 6:{
-: 7: int a,b, result;
-: 8: char opr;
-: 9:
1: 10: if(argc!=4)
1: 10-block 0
-: 11: {
#####: 12: printf("Invalid arguments...\n");
$$$$$: 12-block 0
#####: 13: return -1;
-: 14: }
-: 15:
-: 16: //get values
1: 17: a = atoi(argv[1]);
1: 18: b = atoi(argv[3]);
-: 19:
-: 20: //get operator
1: 21: opr=argv[2][0];
-: 22:
-: 23: //calculate according to operator
1: 24: switch(opr)
1: 24-block 0
-: 25: {
1: 26: case '+':
1: 27: result = add_(a, b);
1: 27-block 0
-: 28:
1: 29: break;
#####: 30: case '-':
#####: 31: result=sub_(a,b);
$$$$$: 31-block 0
#####: 32: break;
#####: 33: case '_':
#####: 34: result=multiply_(a,b);
$$$$$: 34-block 0
#####: 35: break;
#####: 36: case '/':
#####: 37: result = div_(a,b);
$$$$$: 37-block 0
#####: 38: default:
#####: 39: result=0;
#####: 40: break;
$$$$$: 40-block 0
-: 41: }
-: 42:
1: 43: if(opr=='+' || opr=='-' || opr=='_'|| opr== '/')
1: 43-block 0
$$$$$: 43-block 1
$$$$$: 43-block 2
$$$$$: 43-block 3
1: 44: printf("Result: %d %c %d = %d\n",a,opr,b,result);
1: 44-block 0
-: 45: else
#####: 46: printf("Undefined Operator...\n");
$$$$$: 46-block 0
-: 47:
1: 48: return 0;
1: 48-block 0
-: 49:}
-: 50:
-: 51:/**
-: 52: * Function to add two numbers
-: 53: */
1: 54:float add_(float num1, float num2)
1: 54-block 0
-: 55:{
1: 56: return num1 + num2;
1: 56-block 0
-: 57:}
-: 58:
-: 59:/**
-: 60: * Function to subtract two numbers
-: 61: */
#####: 62:float sub_(float num1, float num2)
$$$$$: 62-block 0
-: 63:{
#####: 64: return num1 - num2;
$$$$$: 64-block 0
-: 65:}
-: 66:
-: 67:/**
-: 68: * Function to multiply two numbers
-: 69: */
#####: 70:float multiply_(float num1, float num2)
$$$$$: 70-block 0
-: 71:{
#####: 72: return num1 * num2;
$$$$$: 72-block 0
-: 73:}
-: 74:
-: 75:/**
-: 76: * Function to divide two numbers
-: 77: */
#####: 78:float div_(float num1, float num2)
$$$$$: 78-block 0
-: 79:{
#####: 80: return num1 / num2;
$$$$$: 80-block 0
-: 81:}
If anyone knows how to decipher the block info, specially lines 5,12,13,43 ,64 or knows of any detailed documentation on what it all means, I'd appreciate the help.
Each block is marked by a line with the same line number as the last line of the block and the number of branch and calls in the block. A block is created using a pair of curly braces({}). Line 5 marks the beginning of main block...then as I mentioned for every branch or function call block number is mentioned...Now your if statement has four conditions that means there will be 4 additional blocks which are labeled as 0,1,2,3..All the blocks which are not executed are marked $$$$$, which is true here as you must have passed '+' as the argument so the program never takes the path of other operators and hence block 1,2,3 are marked as $$$$$.
Hope this helps.

Algorithm for generating all possible boolean functions of n variables

For n variables, there exists 2^(2^n) distinct boolean functions. For example, if n=2, then there exists 16 possible boolean functions which can be written in sum of product form, or product of sum forms. The number of possible functions increases exponentially with n.
I am looking for an algorithm which can generate all these possible boolean rules for n variables. I have tried to search at various places, but have not found anything suitable till now. Most of the algorithms are related to simplifying or reducing boolean functions to standard forms.
I know even for the number of rules become too large even for n=8 or 9, but can somebody please help me out with the relevant algorithm if it exists?
A boolean function of n variables has 2^n possible inputs. These can be enumerated by printing out the binary representation of values in the range 0 <= x < 2^n.
For each one of the those possible inputs, a boolean function can output 0 or 1. To enumerate all the possibilities (i.e. every possible truth table). List the binary values in range 0 <= x < 2^(2^n).
Here's the algorithm in Python:
from __future__ import print_function
from itertools import product # forms cartesian products
n = 3 # number of variables
print('All possible truth tables for n =', n)
inputs = list(product([0, 1], repeat=n))
for output in product([0, 1], repeat=len(inputs)):
print()
print('Truth table')
print('-----------')
for row, result in zip(inputs, output):
print(row, '-->', result)
The output looks like this:
All possible truth tables for n = 3
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 0
(1, 1, 1) --> 0
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 0
(1, 1, 1) --> 1
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 1
(1, 1, 1) --> 0
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 1
(1, 1, 1) --> 1
... and so on
If you want the output in algebraic form rather than truth tables, the algorithm is the same:
from __future__ import print_function
from itertools import product # forms cartesian products
n = 3 # number of variables
variables = 'abcdefghijklmnopqrstuvwxyz'[:n]
pairs = [('~'+var, var) for var in variables]
print('All possible algebraic expressions for n =', n)
inputs = list(product(*pairs))
for i, outputs in enumerate(product([0, 1], repeat=len(inputs))):
terms = [''.join(row) for row, output in zip(inputs, outputs) if output]
if not terms:
terms = ['False']
print('Function %d:' % i, ' or '.join(terms))
The output looks like this:
All possible algebraic expressions for n = 3
Function 0: False
Function 1: abc
Function 2: ab~c
Function 3: ab~c or abc
Function 4: a~bc
Function 5: a~bc or abc
Function 6: a~bc or ab~c
Function 7: a~bc or ab~c or abc
Function 8: a~b~c
Function 9: a~b~c or abc
Function 10: a~b~c or ab~c
Function 11: a~b~c or ab~c or abc
Function 12: a~b~c or a~bc
Function 13: a~b~c or a~bc or abc
Function 14: a~b~c or a~bc or ab~c
Function 15: a~b~c or a~bc or ab~c or abc
Function 16: ~abc
Function 17: ~abc or abc
Function 18: ~abc or ab~c
Function 19: ~abc or ab~c or abc
Function 20: ~abc or a~bc
Function 21: ~abc or a~bc or abc
Function 22: ~abc or a~bc or ab~c
Function 23: ~abc or a~bc or ab~c or abc
Function 24: ~abc or a~b~c
Function 25: ~abc or a~b~c or abc
Function 26: ~abc or a~b~c or ab~c
Function 27: ~abc or a~b~c or ab~c or abc
Function 28: ~abc or a~b~c or a~bc
Function 29: ~abc or a~b~c or a~bc or abc
Function 30: ~abc or a~b~c or a~bc or ab~c
Function 31: ~abc or a~b~c or a~bc or ab~c or abc
Function 32: ~ab~c
Function 33: ~ab~c or abc
... and so on
As mentioned in comments, there's a one-to-one relation between numbers and truth tables. For example, we can represent the truth table
0 0 0 | 1
0 0 1 | 1
0 1 0 | 0
0 1 1 | 0
1 0 0 | 1
1 0 1 | 0
1 1 0 | 1
1 1 1 | 0
by the binary number 01010011 (the topmost row is represented by the least-significant bit).
It is obviously just a matter of looping over numbers to generate these representations:
for f := 0 to 2^(2^n) - 1:
# do something with f
What can we do with f? We can evaluate it, for example. Say we want to know f(0,1,0). It's as simple as interpreting the argument as the binary number x = 010 and doing some bit-magic:
def evaluate(f, x):
return (f & (1<<x)) != 0
We can also find its disjunctive normal form by just checking which bits are 0:
def dnf(f):
for x := 0 to 2^n - 1:
if f & (1<<x) != 0:
print binary(x) + " OR "
Giving a result like 000 OR 001 OR 100 OR 110 (OR) for the function above.
I've changed the code posted by Raymond Hettinger.
Now you can:
generate all Boolean expressions up to n_ary,
pick a particular function,
perform evaluation, and
get answers in binary or True/False manner.
Code:
from itertools import product
def allBooleanFunctions(kk):
"""Finds all Boolean functions for indegree kk"""
inputs1 = list(product([0, 1], repeat=kk))
variables = 'abcdefghijklmnopqrstuvwxyz'[:kk]
pairs = [('( not '+var+' )', var) for var in variables]
inputs = list(product(*pairs))
bool_func=[]
for i, outputs in enumerate(product([0, 1], repeat=len(inputs))):
terms = [' and '.join(row) for row, output in zip(inputs, outputs) if output]
if not terms:
terms = ['False']
bool_func.append(('('+(') or ('.join(terms))+')'))
return bool_func
n_ary=2 # number of inputs; keep it n_ary<=5
boolean_function_analytical=allBooleanFunctions(n_ary)
print('All Boolean functions of indegree:'+str(n_ary)+'\n')
print(boolean_function_analytical)
print
print('A Boolean function:'+'\n')
print(boolean_function_analytical[2])
# Evaluate third boolean function:
a=1 # first input
b=0 # second input
c=0 # third input
d=0 # fourth input
print('a='+str(a)+'; b='+str(b)+'; c='+str(c)+'; d='+str(d)+'\n')
print('Evaluation in 0/1 manner:')
print(int(eval((boolean_function_analytical[2]))))
print('Evaluation in True/False manner:')
print(bool(eval((boolean_function_analytical[2]))))
Result:
All Boolean functions of indegree:2
['(False)', '(a and b)', '(a and ( not b ))', '(a and ( not b )) or (a and b)', '(( not a ) and b)', '(( not a ) and b) or (a and b)', '(( not a ) and b) or (a and ( not b ))', '(( not a ) and b) or (a and ( not b )) or (a and b)', '(( not a ) and ( not b ))', '(( not a ) and ( not b )) or (a and b)', '(( not a ) and ( not b )) or (a and ( not b ))', '(( not a ) and ( not b )) or (a and ( not b )) or (a and b)', '(( not a ) and ( not b )) or (( not a ) and b)', '(( not a ) and ( not b )) or (( not a ) and b) or (a and b)', '(( not a ) and ( not b )) or (( not a ) and b) or (a and ( not b ))', '(( not a ) and ( not b )) or (( not a ) and b) or (a and ( not b )) or (a and b)']
A Boolean function:
(a and ( not b ))
a=1; b=0; c=0; d=0
Evaluation in 0/1 manner:
1
Evaluation in True/False manner:
True
Have fun!!!

scala implicit performance

This comes up regularly. Functions coded up using generics are signifficnatly slower in scala. See example below. Type specific version performs about a 1/3 faster than the generic version. This is doubly surprising given that the generic component is outside of the expensive loop. Is there a known explanation for this?
def xxxx_flttn[T](v: Array[Array[T]])(implicit m: Manifest[T]): Array[T] = {
val I = v.length
if (I <= 0) Array.ofDim[T](0)
else {
val J = v(0).length
for (i <- 1 until I) if (v(i).length != J) throw new utl_err("2D matrix not symetric. cannot be flattened. first row has " + J + " elements. row " + i + " has " + v(i).length)
val flt = Array.ofDim[T](I * J)
for (i <- 0 until I; j <- 0 until J) flt(i * J + j) = v(i)(j)
flt
}
}
def flttn(v: Array[Array[Double]]): Array[Double] = {
val I = v.length
if (I <= 0) Array.ofDim[Double](0)
else {
val J = v(0).length
for (i <- 1 until I) if (v(i).length != J) throw new utl_err("2D matrix not symetric. cannot be flattened. first row has " + J + " elements. row " + i + " has " + v(i).length)
val flt = Array.ofDim[Double](I * J)
for (i <- 0 until I; j <- 0 until J) flt(i * J + j) = v(i)(j)
flt
}
}
You can't really tell what you're measuring here--not very well, anyway--because the for loop isn't as fast as a pure while loop, and the inner operation is quite inexpensive. If we rewrite the code with while loops--the key double-iteration being
var i = 0
while (i<I) {
var j = 0
while (j<J) {
flt(i * J + j) = v(i)(j)
j += 1
}
i += 1
}
flt
then we see that the bytecode for the generic case is actually dramatically different. Non-generic:
133: checkcast #174; //class "[D"
136: astore 6
138: iconst_0
139: istore 5
141: iload 5
143: iload_2
144: if_icmpge 191
147: iconst_0
148: istore 4
150: iload 4
152: iload_3
153: if_icmpge 182
// The stuff above implements the loop; now we do the real work
156: aload 6
158: iload 5
160: iload_3
161: imul
162: iload 4
164: iadd
165: aload_1
166: iload 5
168: aaload // v(i)
169: iload 4
171: daload // v(i)(j)
172: dastore // flt(.) = _
173: iload 4
175: iconst_1
176: iadd
177: istore 4
// Okay, done with the inner work, time to jump around
179: goto 150
182: iload 5
184: iconst_1
185: iadd
186: istore 5
188: goto 141
It's just a bunch of jumps and low-level operations (daload and dastore being the key ones that load and store a double from an array). If we look at the key inner part of the generic bytecode, it instead looks like
160: getstatic #30; //Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
163: aload 7
165: iload 6
167: iload 4
169: imul
170: iload 5
172: iadd
173: getstatic #30; //Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
176: aload_1
177: iload 6
179: aaload
180: iload 5
182: invokevirtual #107; //Method scala/runtime/ScalaRunTime$.array_apply:(Ljava/lang/Object;I)Ljava/lang/Object;
185: invokevirtual #111; //Method scala/runtime/ScalaRunTime$.array_update:(Ljava/lang/Object;ILjava/lang/Object;)V
188: iload 5
190: iconst_1
191: iadd
192: istore 5
which, as you can see, has to call methods to do the array apply and update. The bytecode for that is a huge mess of stuff like
2: aload_3
3: instanceof #98; //class "[Ljava/lang/Object;"
6: ifeq 18
9: aload_3
10: checkcast #98; //class "[Ljava/lang/Object;"
13: iload_2
14: aaload
15: goto 183
18: aload_3
19: instanceof #100; //class "[I"
22: ifeq 37
25: aload_3
26: checkcast #100; //class "[I"
29: iload_2
30: iaload
31: invokestatic #106; //Method scala/runtime/BoxesRunTime.boxToInteger:
34: goto 183
37: aload_3
38: instanceof #108; //class "[D"
41: ifeq 56
44: aload_3
45: checkcast #108; //class "[D"
48: iload_2
49: daload
50: invokestatic #112; //Method scala/runtime/BoxesRunTime.boxToDouble:(
53: goto 183
which basically has to test each type of array and box it if it's the type you're looking for. Double is pretty near the front (3rd of 10), but it's still a pretty major overhead, even if the JVM can recognize that the code ends up being box/unbox and therefore doesn't actually need to allocate memory. (I'm not sure it can do that, but even if it could it wouldn't solve the problem.)
So, what to do? You can try [#specialized T], which will expand your code tenfold for you, as if you wrote each primitive array operation by yourself. Specialization is buggy in 2.9 (should be less so in 2.10), though, so it may not work the way you hope. If speed is of the essence--well, first, write while loops instead of for loops (or at least compile with -optimise which helps for loops out by a factor of two or so!), and then consider either specialization or writing the code by hand for the types you require.
This is due to boxing, when you apply the generic to a primitive type and use containing arrays (or the type appearing plain in method signatures or as member).
Example
In the following trait, after compilation, the process method will take an erased Array[Any].
trait Foo[A]{
def process(as: Array[A]): Int
}
If you choose A to be a value/primitive type, like Double it has to be boxed. When writing the trait in a non-generic way (e.g. with A=Double), process is compiled to take an Array[Double], which is a distinct array type on the JVM. This is more efficient, since in order to store a Double inside the Array[Any], the Double has to be wrapped (boxed) into an object, a reference to which gets stored inside the array. The special Array[Double] can store the Double directly in memory as a 64-Bit value.
The #specialized-Annotation
If you feel adventerous, you can try the #specialized keyword (it's pretty buggy and crashes the compiler often). This makes scalac compile special versions of a class for all or selected primitive types. This only makes sense, if the type parameter appears plain in type signatures (get(a: A), but not get(as: Seq[A])) or as a type paramter to Array. I think you'll receive a warning if speicialization is pointless.

Resources