mapっぽくなにか
先日気になったのでどうなのかなーって思って調べた話。(for Perl)
my @array = ( 1..1_000 );
この配列の値をハッシュのkeyにして扱いやすくしてあれこれしていく、っていうを割とやるのですが、 だいたい
my %map = map { $_ => 1 } @array;
とか
my %map;
foreach my $id ( @array ) {
$map{$id} = 1;
}
とかってやってたのですが先日
my %map;
@map{@array} = ();
outout が \%map = { 1 => undef, 2 => undef, .... } こう書いた方が速いです、というコメントを見て、こんな書き方できるのかーって思ったのと 本当に速いんですか?って思ったので調べた。
#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw(gettimeofday tv_interval);
my @array = ( 1..1_000 );
{
my $t0 = [gettimeofday];
my %map;
@map{@array} = ();
my $elapsed = tv_interval($t0);
print '--@map{@array}--' . "\n";
print $elapsed * 1000 . "\n";
}
{
my $t0 = [gettimeofday];
my %map = map { $_ => 1 } @array;
my $elapsed = tv_interval($t0);
print '--map--' . "\n";
print $elapsed * 1000 . "\n";
}
{
my $t0 = [gettimeofday];
my %map;
foreach my $id ( @array ) {
$map{$id} = 1;
}
my $elapsed = tv_interval($t0);
print '--foreach--' . "\n";
print $elapsed * 1000 . "\n";
}
{
my $t0 = [gettimeofday];
my %map;
for my $id ( @array ) {
$map{$id} = 1;
}
my $elapsed = tv_interval($t0);
print '--for--' . "\n";
print $elapsed * 1000 . "\n";
}
1;
実行結果
1_000_000で実行
$perl sample.pl
--@map{@array}--
740.508
--map--
1199.097
--foreach--
639.542
--for--
650.275
10_000_000 で実行
$perl sample.pl 10_000_000
--@map{@array}--
11308.191
--map--
16796.802
--foreach--
9985.983
--for--
10101.491
※ foreachとforが定期的にどっちが速いのかわからなくなるのでまた調べた。 一応 perlsyn - perldoc.perl.org
The foreach keyword is actually a synonym for the for keyword, so you can use either
for と foreachはperldocで同義ですよって言われている。 foreachが速いって思ってたんだけどPHPとごっちゃになってるのかな。
[PHP]ループのメモリ使用量と処理速度を比較しました - Qiita
とにかく
foreach = for > @map{@array} > map
の順で速かったので mapより @map{@array} にしたほうが速かった。
ちなみに valueがundefになって速いなら
my %map;
foreach my $id ( @array ) {
$map{$id} = undef;
}
にしたら速くなるのでは?と思ったけどそんなことはなかった。
まあけど、可読性がよくなるという理由以外にmap使わないようにしましょうって話ですね。
ワンライナーかっこいいという理由でmap使いがちでした/(^o^)\おわた
GCPで定期実行
GCPのcron.yaml はAPIを定期的に叩くって感じ。
なので、外部アクセスが定期的に動かしたい処理を入れたpathにアクセスがあると実行されてしまう。
それを回避するには、
cron.yaml からのアクセスにはヘッダーに下記の情報が含まれるので、それを利用する。
ドキュメントには
cron サービスからのリクエストには、次の HTTP ヘッダーも含まれます。 X-Appengine-Cron: true
とあるが、これは違うっぽい?
HTTP_X_APPENGINE_CRON: true
っぽい。 (けどまだちゃんと確認できてない)
Djangoでやってたので
def hoge(request)
if not request.META.get('HTTP_X_APPENGINE_CRON') is None:
## 実行したい処理
みたいな感じだと動いた(^O^)/やった〜
ただ、cron.yamlは gcloud app deploy cron.yaml, gcloud app deploy を打ったあとだとすぐは動かない...?
ようで手動でcron動かすとずっと500エラーになってしまった。
一晩寝かせたら動いていて、なぞof謎だった。
参考
HerokuでRailsのtimezoneの設定
Herokuのtimezoneの設定
heroku config:add TZ=Asia/Tokyo
heroku run bash Running bash on ⬢ yorakashi... up, run.3031 (Hobby) ~ $ date Wed Apr 17 23:45:05 JST 2019
ここでJSTになっていることを確認
PostgreSQLのtimezone
herokuのDBにPSequelから接続する - ゆるゆる〜tech ver〜 こんな感じで PSequelから入って、Queryのところで
alter database your_database_name set timezone = 'Asia/Tokyo';
select current_timestamp;
で確認
config/application.rb
config.time_zone = 'Tokyo'
config.active_record.default_timezone = :local
scriptでreserved_on みたいな datetimeを設定してレコード突っ込んでたら、意図しない時間に表示されてあれ???ってなった。
config.active_record.default_timezone = :local がいなかった...しゅん....
Unity: Android用のPluginを作る Kotlin
はまったこと
ggってでてくる感じでいけるけど、Make Module 'hogehoge' すると
import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity;
がないよって怒られる。
cp /Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/mono/Release/Classes/classes.jar /Users/xxxx/AndroidStudioProjects/[APP_NAME]/[Plugin_Name]/libs/
にこぴーすればいける
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//省略
compile files('/Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/mono/Release/Classes/classes.jar')
compile files('/Users/UserName/Library/Android/sdk/platforms/android-26/android.jar') /*Androidプラグインとして利用するため追加*/
}
この下の2行を足す。
compile files は書き方が古いみたいだけど、ちゃんとした書き方がわからなかった。
classes.jar の場所サイトに書いてあるのと違ってちょっとハマった。
ちなみに Unity 3.3f
そしたらMake Module できました!やったね!
そしたらxxxxx(plugin name)/build/outputs/aar ってディレクトリができてて、.aarができている。
参考
heroku run rake db:seedが反映されない
require "csv"
CSV.foreach('db/csv/hoge.csv') do |row|
Member.create(:gender => row[1], :age => row[2], :name => "hoge", :status => 1)
end
みたいなスクリプトをかいて、
rake db:seed
を実行するとローカルのDBには反映された。
けれど、
Rails5 heroku run rake db:seed を実行しても
何も反映されない。
なんともこの変更した差分を git push heroku master していないだけだった。
そういうところやぞ
ストアドプロシージャでさくっと100万レコード作る
クエリーチューニングするときにスクリプト使って入れるよりさくっと欲しいときに。。。
CREATE TABLE `test_table` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `tester_id` int(10) UNSIGNED NOT NULL, `hoge_id` int(10) UNSIGNED NOT NULL, `fuga_id` int(10) UNSIGNED NOT NULL, `status` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0: incactive, 1,: active', `created_on` int(10) unsigned NOT NULL, `updated_on` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
1回消しておく
drop procedure if exists doWhile;
作る
DELIMITER //
CREATE PROCEDURE doWhile()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE (i < 100) DO
INSERT INTO test_table (tester_id, hoge_id,fuga_id, status, created_on ) VALUES (i, 29905, 119619, (CAST(RAND() * 2 AS UNSIGNED)), unix_timestamp());
SET i = i+1;
END WHILE;
END;
//
実行する
CALL doWhile();